summaryrefslogtreecommitdiff
path: root/index.php
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2025-02-20 12:13:12 +0100
committerDaniel Weipert <git@mail.dweipert.de>2025-02-20 12:13:12 +0100
commit4fd85782abf9005a0d27d7890023a21d9dad6ef3 (patch)
treec8b2830f34c2d2acb431fdb54a9f1bf03abf50fb /index.php
parentb98893f7d8b7ae95955eb7d26921b81818456ce7 (diff)
add file treeHEADmain
Diffstat (limited to 'index.php')
-rw-r--r--index.php185
1 files changed, 170 insertions, 15 deletions
diff --git a/index.php b/index.php
index a5342f8..9f8b568 100644
--- a/index.php
+++ b/index.php
@@ -14,13 +14,10 @@ function find_projects(string $path, array $projects = []): array {
return $projects;
}
-$projects_path = realpath($_GET['projects']);
-$projects = find_projects($projects_path);
-
-function parse_log(): array|null {
+function parse_log(string $path): array|null {
$proxy = md5(strval(microtime(true)));
$process = proc_open(
- "git log " . "--pretty=format:'{%n {$proxy}commit{$proxy}: {$proxy}%H{$proxy},%n {$proxy}author{$proxy}: {$proxy}%aN <%aE>{$proxy},%n {$proxy}date{$proxy}: {$proxy}%ad{$proxy},%n {$proxy}message{$proxy}: {$proxy}%s{$proxy}%n},'",
+ "git -C {$path} log " . "--pretty=format:'{%n {$proxy}commit{$proxy}: {$proxy}%H{$proxy},%n {$proxy}author{$proxy}: {$proxy}%aN <%aE>{$proxy},%n {$proxy}date{$proxy}: {$proxy}%ad{$proxy},%n {$proxy}message{$proxy}: {$proxy}%s{$proxy}%n},'",
[
["pipe", "r"],
["pipe", "w"],
@@ -38,9 +35,9 @@ function parse_log(): array|null {
return $json;
}
-function parse_status(): array {
+function parse_status(string $path): array {
$process = proc_open(
- "git status --porcelain=v2 --branch",
+ "git -C {$path} status --porcelain=v2 --branch",
[
["pipe", "r"],
["pipe", "w"],
@@ -120,17 +117,175 @@ function parse_status(): array {
return $status;
}
-foreach ($projects as $project) {
- chdir($project);
+function get_file_tree(string $path, string $revision, string $tree_base_path): array
+{
+ $proxy = md5(strval(microtime(true)));
+ $process = proc_open(
+ "git -C {$path} ls-tree {$revision} {$tree_base_path}" . " --format='{%n {$proxy}mode{$proxy}: {$proxy}%(objectmode){$proxy},%n {$proxy}type{$proxy}: {$proxy}%(objecttype){$proxy},%n {$proxy}name{$proxy}: {$proxy}%(objectname){$proxy},%n {$proxy}size{$proxy}: {$proxy}%(objectsize){$proxy},%n {$proxy}path{$proxy}: {$proxy}%(path){$proxy}%n},'",
+ [
+ ["pipe", "r"],
+ ["pipe", "w"],
+ ["pipe", "w"],
+ ],
+ $pipes
+ );
+
+ $output = stream_get_contents($pipes[1]);
+ $string = str_replace(['"', $proxy], ['\\"', '"'], $output);
+ $string = "[" . rtrim(trim($string), ",") . "]";
+
+ $tree = json_decode($string, true);
+
+ return $tree;
+}
+
+
+function template_root(string $content, array $meta = []): string
+{
+ $meta = array_replace_recursive([
+ "title" => "phpgit - single file git web frontend",
+ ], $meta);
+
+ ob_start();
+
+ ?>
+ <html>
+ <head>
+ <title><?php echo $meta["title"]; ?></title>
+ </head>
+ <body><?php echo $content; ?></body>
+ </html>
+ <?php
+
+ return ob_get_clean();
+}
+
+
+$projects_path = realpath($_ENV["PHPGIT_PROJECTS_PATH"]);
+
+$url = parse_url("http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
+
+ob_start();
+
+if ($url["path"] == "/") {
+ $projects = find_projects($projects_path);
+
+ // sort by date
+ usort($projects, function ($a, $b) {
+ $a_log = parse_log($a);
+
+ if (file_exists(".git/info/web/last-modified")) {
+ $a_date = new DateTime(file_get_contents(".git/info/web/last-modified"));
+ } else if (count($a_log) > 0) {
+ $a_date = new DateTime($a_log[0]["date"]);
+ } else {
+ $a_date = date_create()->setTimestamp(0);
+ }
+
+ $b_log = parse_log($b);
+
+ if (file_exists(".git/info/web/last-modified")) {
+ $b_date = new DateTime(file_get_contents(".git/info/web/last-modified"));
+ } else if (count($b_log) > 0) {
+ $b_date = new DateTime($b_log[0]["date"]);
+ } else {
+ $b_date = date_create()->setTimestamp(0);
+ }
+
+ return $b_date <=> $a_date;
+ });
+
+ // build list
+ ?>
+ <table>
+ <thead>
+ <tr>
+ <td>Name</td>
+ <td>Description</td>
+ <td>Last Activity</td>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+
+ foreach ($projects as $project) {
+ $name = trim(str_replace($projects_path, "", $project), "/");
+
+ ?><tr><?php
+
+ ?><td><a href="<?php echo $name; ?>/tree"><?php
+ echo $name;
+ ?></a></td><?php
+
+ $status = parse_status($project);
+
+ echo "<td></td>";
+
+ $log = parse_log($project);
+
+ if (count($log) > 0) {
+ $date = new DateTime($log[0]["date"]);
+ echo "<td>" . $date->format("Y-m-d") . "</td>";
+ }
+
+ ?></tr><?php
+ }
+
+ ?>
+ </tbody>
+ </table>
+ <?php
+}
+
- echo $project . "<br>";
+// /$project/tree/$file_path
+elseif (preg_match("#(.*)/tree/?(.*)#", $url["path"], $matches)) {
+ $project = ltrim($matches[1], "/");
+ $file_path = rtrim($matches[2], "/");
- $status = parse_status();
- foreach ($status["files"] as $file) {
- var_dump($file);
+ // get tree
+ $tree = get_file_tree("$projects_path/$project", "HEAD", "./{$file_path}/");
+
+ // show breadcrumbs
+ $breadcrumbs = explode("/", $file_path);
+ echo "<a href='/$project/tree'>root</a>";
+ $crumb_parts = "";
+ foreach ($breadcrumbs as $idx => $crumb) {
+ $crumb_parts .= "/$crumb";
+ echo "/<a href='/$project/tree$crumb_parts'>$crumb</a>";
}
- foreach (parse_log() as $commit) {
- // echo "<a href=\"$commit[commit]\">$commit[message]</a><br>";
+ // build list
+ ?>
+ <table>
+ <thead>
+ <tr>
+ <td>File</td>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+
+ foreach ($tree as $file) {
+ $relative_path = str_replace("$file_path/", "", $file["path"]);
+
+ ?><tr><?php
+
+ ?><td><a href="<?php echo "$url[path]/$relative_path"; ?>"><?php echo $relative_path; ?></a><td><?php
+
+ ?></tr><?php
}
+
+ ?>
+ </tbody>
+ </table>
+ <?php
}
+
+else {
+ $path = $projects_path . $url["path"];
+ var_dump(parse_log($path));
+}
+
+// display
+echo template_root(ob_get_clean());