From 44996fe6f09b42648da19df97dd444d1aac8b003 Mon Sep 17 00:00:00 2001 From: shalvah Date: Sat, 15 Oct 2022 20:07:20 +0200 Subject: [PATCH] Support custom "Last updated at" label --- config/scribe.php | 12 ++++++ phpstan.neon | 1 - phpunit.xml | 1 + .../views/themes/default/sidebar.blade.php | 2 +- .../Strategies/Responses/ResponseCalls.php | 8 +++- src/Writing/HtmlWriter.php | 42 +++++++++++++++---- tests/Unit/HtmlWriterTest.php | 33 +++++++++++++++ 7 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 tests/Unit/HtmlWriterTest.php diff --git a/config/scribe.php b/config/scribe.php index 49e29565..7d96eb10 100644 --- a/config/scribe.php +++ b/config/scribe.php @@ -346,6 +346,18 @@ */ 'logo' => false, + /** + * Customize the "Last updated" value displayed in the docs by specifying tokens and formats. + * Examples: + * - {date:F j Y} => March 28, 2022 + * - {git:short} => Short hash of the last Git commit + * + * Available tokens are `{date:}` and `{git:}`. + * The format you pass to `date` will be passed to PhP's `date()` function. + * The format you pass to `git` can be either "short" or "long". + */ + 'last_updated' => 'Last updated: {date:F j, Y}', + 'examples' => [ /* * If you would like the package to generate the same example values for parameters on each run, diff --git a/phpstan.neon b/phpstan.neon index e1e971ec..dcd665a0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,7 +3,6 @@ parameters: reportUnmatchedIgnoredErrors: true inferPrivatePropertyTypeFromConstructor: true ignoreErrors: - - '#Call to an undefined static method Illuminate\\Support\\Facades\\URL::forceRootUrl\(\)#' - '#Call to an undefined method Illuminate\\Routing\\Route::versions\(\).#' - '#Call to an undefined method Illuminate\\Contracts\\Validation\\Validator::getRules\(\).#' - '#Call to an undefined method ReflectionType::getName\(\).#' diff --git a/phpunit.xml b/phpunit.xml index 61978891..ca7993a0 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -46,6 +46,7 @@ tests/Unit/ValidationRuleParsingTest.php + tests/Unit/HtmlWriterTest.php diff --git a/resources/views/themes/default/sidebar.blade.php b/resources/views/themes/default/sidebar.blade.php index 84d6f70b..056292d5 100644 --- a/resources/views/themes/default/sidebar.blade.php +++ b/resources/views/themes/default/sidebar.blade.php @@ -58,6 +58,6 @@ @endif diff --git a/src/Extracting/Strategies/Responses/ResponseCalls.php b/src/Extracting/Strategies/Responses/ResponseCalls.php index 46a9e9f9..57f07391 100644 --- a/src/Extracting/Strategies/Responses/ResponseCalls.php +++ b/src/Extracting/Strategies/Responses/ResponseCalls.php @@ -129,7 +129,8 @@ private function configureEnvironment(array $rulesToApply) * * @return Request */ - protected function prepareRequest(Route $route, array $rulesToApply, array $urlParams, array $bodyParams, array $queryParams, array $fileParameters, array $headers): Request + protected function prepareRequest(Route $route, array $rulesToApply, array $urlParams, array $bodyParams, + array $queryParams, array $fileParameters, array $headers): Request { $uri = Utils::getUrlWithBoundParameters($route->uri(), $urlParams); $routeMethods = $this->getMethods($route); @@ -146,7 +147,10 @@ protected function prepareRequest(Route $route, array $rulesToApply, array $urlP // Always use the current app domain for response calls $rootUrl = config('app.url'); - $request = Request::create("$rootUrl/$uri", $method, [], $cookies, $fileParameters, $this->transformHeadersToServerVars($headers), json_encode($bodyParams)); + $request = Request::create( + "$rootUrl/$uri", $method, [], $cookies, $fileParameters, + $this->transformHeadersToServerVars($headers), json_encode($bodyParams) + ); // Doing it again to catch any ones we didn't transform properly. $request = $this->addHeaders($request, $route, $headers); diff --git a/src/Writing/HtmlWriter.php b/src/Writing/HtmlWriter.php index 3c2297d8..dc83131b 100644 --- a/src/Writing/HtmlWriter.php +++ b/src/Writing/HtmlWriter.php @@ -104,7 +104,7 @@ protected function transformMarkdownFileToHTML(string $markdownFilePath): string return $this->markdownParser->text(file_get_contents($markdownFilePath)); } - protected function getMetadata(): array + public function getMetadata(): array { $links = []; @@ -117,26 +117,50 @@ protected function getMetadata(): array } $auth = $this->config->get('auth'); - if ($auth['in'] === 'bearer' || $auth['in'] === 'basic') { - $auth['name'] = 'Authorization'; - $auth['location'] = 'header'; - $auth['prefix'] = ucfirst($auth['in']) . ' '; - } else { - $auth['location'] = $auth['in']; - $auth['prefix'] = ''; + if ($auth) { + if ($auth['in'] === 'bearer' || $auth['in'] === 'basic') { + $auth['name'] = 'Authorization'; + $auth['location'] = 'header'; + $auth['prefix'] = ucfirst($auth['in']) . ' '; + } else { + $auth['location'] = $auth['in']; + $auth['prefix'] = ''; + } } return [ 'title' => $this->config->get('title') ?: config('app.name', '') . ' Documentation', 'example_languages' => $this->config->get('example_languages'), 'logo' => $this->config->get('logo') ?? false, - 'last_updated' => date("F j Y"), + 'last_updated' => $this->getLastUpdated(), 'auth' => $auth, 'try_it_out' => $this->config->get('try_it_out'), 'links' => array_merge($links, ['Documentation powered by Scribe ✍']), ]; } + protected function getLastUpdated() + { + $lastUpdated = $this->config->get('last_updated', 'Last updated: {date:F j, Y}'); + + $tokens = [ + "date" => fn($format) => date($format), + "git" => fn($option) => match ($option) { + "short" => trim(shell_exec('git rev-parse --short HEAD')), + "long" => trim(shell_exec('git rev-parse HEAD')), + }, + ]; + + foreach ($tokens as $token => $resolver) { + $matches = []; + if(preg_match('#(\{'.$token.':(.+?)})#', $lastUpdated, $matches)) { + $lastUpdated = str_replace($matches[1], $resolver($matches[2]), $lastUpdated); + } + } + + return $lastUpdated; + } + protected function getHeadings(array $headingsBeforeEndpoints, array $endpointsByGroupAndSubgroup, array $headingsAfterEndpoints) { $headings = []; diff --git a/tests/Unit/HtmlWriterTest.php b/tests/Unit/HtmlWriterTest.php new file mode 100644 index 00000000..741f3211 --- /dev/null +++ b/tests/Unit/HtmlWriterTest.php @@ -0,0 +1,33 @@ + "http://local.test", "title" => "API Docs"]; + $config["last_updated"] = ''; + $writer = new HtmlWriter(new DocumentationConfig($config)); + $lastUpdated = $writer->getMetadata()["last_updated"]; + $this->assertEquals('', $lastUpdated); + + $config["last_updated"] = "Last updated on {date:l}"; + $writer = new HtmlWriter(new DocumentationConfig($config)); + $lastUpdated = $writer->getMetadata()["last_updated"]; + $today = date("l"); + $this->assertEquals("Last updated on $today", $lastUpdated); + + $config["last_updated"] = "Last updated on {date:l, jS F} (Git commit {git:short})"; + $writer = new HtmlWriter(new DocumentationConfig($config)); + $lastUpdated = $writer->getMetadata()["last_updated"]; + $date = date("l, jS F"); + $commit = trim(shell_exec('git rev-parse --short HEAD')); + $this->assertEquals("Last updated on $date (Git commit $commit)", $lastUpdated); + } +}