diff options
Diffstat (limited to 'index.php')
| -rw-r--r-- | index.php | 127 |
1 files changed, 109 insertions, 18 deletions
@@ -15,10 +15,17 @@ function find_projects(string $path, array $projects = []): array { $directories = glob($path . "/{.[!.],}*", GLOB_ONLYDIR | GLOB_BRACE); if (array_search("$path/.git", $directories) !== false) { + app_log("Found $path"); $projects[] = $path; } else { - if (count(array_intersect(scandir($path), ["HEAD", "objects", "refs"])) == 3) { + $scan = @scandir($path); + if (! $scan) { + return $projects; + } + + if (count(array_intersect($scan, ["HEAD", "objects", "refs"])) == 3) { + app_log("Found $path"); $projects[] = $path; } else { @@ -40,14 +47,18 @@ $cache_parse_log = []; */ function parse_log(string $path): array { global $cache_parse_log; - + + app_log("Getting log at $path"); + if (isset($cache_parse_log[$path])) { return $cache_parse_log[$path]; } - + + app_log("Parsing log at $path"); + $proxy = md5(strval(microtime(true))); $process = proc_open( - "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},'", + "git -C \"{$path}\" log " . "--pretty=format:'{{$proxy}commit{$proxy}: {$proxy}%H{$proxy}, {$proxy}author{$proxy}: {$proxy}%aN <%aE>{$proxy}, {$proxy}date{$proxy}: {$proxy}%ad{$proxy}, {$proxy}message{$proxy}: {$proxy}%B{$proxy}},'", [ ["pipe", "r"], ["pipe", "w"], @@ -57,7 +68,13 @@ function parse_log(string $path): array { ); $output = stream_get_contents($pipes[1]); - $string = str_replace(['"', $proxy], ['\\"', '"'], $output); + + // remove git-added newlines + $string = str_replace("},\n{", "},{", $output); + $string = rtrim($string, "\n"); + + $string = str_replace("\n", "\\n", $string); + $string = str_replace(['"', $proxy], ['\\"', '"'], $string); $string = "[" . rtrim($string, ",") . "]"; $json = json_decode($string, true); @@ -70,6 +87,8 @@ function parse_log(string $path): array { * parse git status at $path */ function parse_status(string $path): array { + app_log("Parsing status at $path"); + $process = proc_open( "git -C \"{$path}\" status --porcelain=v2 --branch", [ @@ -221,6 +240,13 @@ function read_object_file(string $path, string $name): string ## + +function app_log(string $message): void +{ + error_log($message); +} + + /** * urlencode whole $url */ @@ -249,7 +275,7 @@ function template_root(string $content, array $meta = []): string $meta = array_replace_recursive([ "title" => "phpgit - single file git web frontend", ], $meta); - + ob_start(); ?> @@ -270,6 +296,9 @@ function template_root(string $content, array $meta = []): string word-break: break-word; } } + td { + padding: 0.25rem 0.5rem; + } </style> </head> <body><?php echo $content; ?></body> @@ -280,6 +309,25 @@ function template_root(string $content, array $meta = []): string } +function template_project(string $project_path, string $content): string +{ + $project_path = trim($project_path, "/"); + + ob_start(); + + ?> + <nav><ul> + <li><a href="/<?php echo uri_encode($project_path); ?>">root</a></li> + <li><a href="/<?php echo uri_encode($project_path); ?>/tree">tree</a></li> + <li><a href="/<?php echo uri_encode($project_path); ?>/log">log</a></li> + </ul></nav> + <main><?php echo $content; ?></main> + <?php + + return template_root(ob_get_clean()); +} + + /** * build breadcrumbs */ @@ -329,9 +377,9 @@ if ($url["path"] == "/") { } 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) { @@ -339,7 +387,7 @@ if ($url["path"] == "/") { } else { $b_date = date_create()->setTimestamp(0); } - + return $b_date <=> $a_date; }); @@ -373,7 +421,7 @@ if ($url["path"] == "/") { if (count($log) > 0) { $date = new DateTime($log[0]["date"]); - echo "<td>" . $date->format("Y-m-d") . "</td>"; + echo "<td>" . $date->format("Y-m-d") . "</td>"; } ?></tr><?php @@ -383,6 +431,8 @@ if ($url["path"] == "/") { </tbody> </table> <?php + + echo template_root(ob_get_clean()); } @@ -408,11 +458,11 @@ elseif (preg_match("#(.*)/tree/?(.*)#", $url["path"], $matches)) { </thead> <tbody> <?php - + foreach ($tree as $file) { $current_file_path = empty($file_path) ? "" : $file_path . "/"; $basename = basename($file["path"]); - + ?><tr><?php ?><td><?php echo $file["mode"]; ?></td><?php @@ -422,7 +472,7 @@ elseif (preg_match("#(.*)/tree/?(.*)#", $url["path"], $matches)) { else: ?><td><a href="<?php echo uri_encode("/$project/tree/$current_file_path$basename"); ?>"><?php echo $basename; ?></a><td><?php endif; - + ?></tr><?php } @@ -430,6 +480,8 @@ elseif (preg_match("#(.*)/tree/?(.*)#", $url["path"], $matches)) { </tbody> </table> <?php + + echo template_project($project, ob_get_clean()); } @@ -437,7 +489,7 @@ elseif (preg_match("#(.*)/tree/?(.*)#", $url["path"], $matches)) { elseif (preg_match("#(.*)/blob/?(.*)#", $url["path"], $matches)) { $project = urldecode(ltrim($matches[1], "/")); $file_path = urldecode(rtrim($matches[2], "/")); - + // show breadcrumbs echo breadcrumbs("/$project/tree", "/$project/tree/$file_path"); @@ -467,14 +519,53 @@ elseif (preg_match("#(.*)/blob/?(.*)#", $url["path"], $matches)) { <?php endif; ?> </div> <?php + + echo template_project($project, ob_get_clean()); +} + + +// Route: /$project/log +elseif (str_ends_with($url["path"], "/log")) { + $project = substr($url["path"], 0, -4); + $log = parse_log($projects_path . $project); + + ?> + <table border> + <thead> + <tr> + <th>Commit</th> + <th>Author</th> + <th>Date</th> + <th>Message</th> + </tr> + </thead> + <tbody> + <?php + + foreach ($log as $entry) { + ?> + <tr> + <td><?php echo $entry["commit"]; ?></td> + <td><?php echo $entry["author"]; ?></td> + <td><?php echo $entry["date"]; ?></td> + <td><?php echo nl2br($entry["message"]); ?></td> + </tr> + <?php + } + + ?> + </tbody> + </table> + <?php + + echo template_project($project, ob_get_clean()); } +// assume project base path else { $path = $projects_path . $url["path"]; var_dump(parse_log($path)); -} - -// display -echo template_root(ob_get_clean()); + echo template_project($url["path"], ob_get_clean()); +} |
