diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2025-02-20 12:13:12 +0100 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2025-02-20 12:13:12 +0100 |
commit | 4fd85782abf9005a0d27d7890023a21d9dad6ef3 (patch) | |
tree | c8b2830f34c2d2acb431fdb54a9f1bf03abf50fb /index.php | |
parent | b98893f7d8b7ae95955eb7d26921b81818456ce7 (diff) |
Diffstat (limited to 'index.php')
-rw-r--r-- | index.php | 185 |
1 files changed, 170 insertions, 15 deletions
@@ -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()); |