Procházet zdrojové kódy

Add isStatic option. Store source in resources/docs and output in public

shalvah před 5 roky
rodič
revize
7bdd05379d

+ 10 - 1
config/apidoc.php

@@ -1,12 +1,21 @@
 <?php
 
 return [
+    /**
+     * The type of documentation output to generate.
+     * - "static" will generate a static HTMl page in the /public/docs folder,
+     * - "laravel" will generate the documentation as Blade files,
+     * so you can add routing and authentication
+     */
+    'type' => 'static',
 
     /*
      * The output path for the generated documentation.
      * This path should be relative to the root of your application.
      */
-    'output' => 'public/docs',
+    'output' => 'public/docs', // index.html, js, css, images, collection.json
+    // source => resources/docs/source
+    // laravel => resources/views/apidoc.blade.php, collection.json
 
     /*
      * The router to be used (Laravel or Dingo).

+ 52 - 29
src/Commands/GenerateDocumentation.php

@@ -100,36 +100,28 @@ class GenerateDocumentation extends Command
     private function writeMarkdown($parsedRoutes)
     {
         $outputPath = $this->docConfig->get('output');
-        $targetFile = $outputPath.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR.'index.md';
-        $compareFile = $outputPath.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR.'.compare.md';
-        $prependFile = $outputPath.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR.'prepend.md';
-        $appendFile = $outputPath.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR.'append.md';
+        $isStatic = $this->docConfig->get('type') === 'static';
 
+        $sourceOutputPath = "resources/docs";
+        $targetFile = $sourceOutputPath.'/source/index.md';
+        $compareFile = $sourceOutputPath.'/source/.compare.md';
+        $prependFile = $sourceOutputPath.'/source/prepend.md';
+        $appendFile = $sourceOutputPath.'/source/append.md';
+
+        // TODO for laravel, replace with {{ route("apidoc.collection") }}
         $infoText = view('apidoc::partials.info')
             ->with('outputPath', ltrim($outputPath, 'public/'))
             ->with('showPostmanCollectionButton', $this->shouldGeneratePostmanCollection());
 
         $settings = ['languages' => $this->docConfig->get('example_languages')];
-        $parsedRouteOutput = $parsedRoutes->map(function ($routeGroup) use ($settings) {
-            return $routeGroup->map(function ($route) use ($settings) {
-                if (count($route['cleanBodyParameters']) && ! isset($route['headers']['Content-Type'])) {
-                    // Set content type if the user forgot to set it
-                    $route['headers']['Content-Type'] = 'application/json';
-                }
-                $route['output'] = (string) view('apidoc::partials.route')
-                    ->with('route', $route)
-                    ->with('settings', $settings)
-                    ->with('baseUrl', $this->baseUrl)
-                    ->render();
-
-                return $route;
-            });
-        });
+        // Generate Markdown for each route
+        $parsedRouteOutput = $this->generateMarkdownOutputForEachRoute($parsedRoutes, $settings);
 
         $frontmatter = view('apidoc::partials.frontmatter')
             ->with('settings', $settings);
         /*
-         * In case the target file already exists, we should check if the documentation was modified
+         * If the target file already exists,
+         * we check if the documentation was modified
          * and skip the modified parts of the routes.
          */
         if (file_exists($targetFile) && file_exists($compareFile)) {
@@ -176,8 +168,8 @@ class GenerateDocumentation extends Command
             ->with('showPostmanCollectionButton', $this->shouldGeneratePostmanCollection())
             ->with('parsedRoutes', $parsedRouteOutput);
 
-        if (! is_dir($outputPath)) {
-            $documentarian->create($outputPath);
+        if (! is_dir($sourceOutputPath)) {
+            $documentarian->create($sourceOutputPath);
         }
 
         // Write output file
@@ -200,21 +192,32 @@ class GenerateDocumentation extends Command
 
         $this->info('Generating API HTML code');
 
-        $documentarian->generate($outputPath);
+        $documentarian->generate($sourceOutputPath);
+        // Move index.html, css/style.css and js/all.js to public/docs
+
+        if ($isStatic) {
+            if (!is_dir($outputPath)) {
+                mkdir($outputPath, 0777, true);
+                mkdir("{$outputPath}/css");
+                mkdir("{$outputPath}/js");
+            }
+            copy("{$sourceOutputPath}/index.html", "{$outputPath}/index.html");
+            copy("{$sourceOutputPath}/css/style.css", "{$outputPath}/css/style.css");
+            copy("{$sourceOutputPath}/js/all.js", "{$outputPath}/js/all.js");
+        }
 
-        $this->info('Wrote HTML documentation to: '.$outputPath.'/index.html');
+        $this->info("Wrote HTML documentation to: {$outputPath}/index.html");
 
         if ($this->shouldGeneratePostmanCollection()) {
             $this->info('Generating Postman collection');
 
-            file_put_contents($outputPath.DIRECTORY_SEPARATOR.'collection.json', $this->generatePostmanCollection($parsedRoutes));
+            file_put_contents("{$outputPath}/collection.json", $this->generatePostmanCollection($parsedRoutes));
         }
 
         if ($logo = $this->docConfig->get('logo')) {
-            copy(
-                $logo,
-                $outputPath.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.'logo.png'
-            );
+            if ($isStatic) {
+                copy($logo, "{$outputPath}/images/logo.png");
+            }
         }
     }
 
@@ -310,4 +313,24 @@ class GenerateDocumentation extends Command
     {
         return $this->docConfig->get('postman.enabled', is_bool($this->docConfig->get('postman')) ? $this->docConfig->get('postman') : false);
     }
+
+    protected function generateMarkdownOutputForEachRoute(Collection $parsedRoutes, array $settings): Collection
+    {
+        $parsedRouteOutput = $parsedRoutes->map(function ($routeGroup) use ($settings) {
+            return $routeGroup->map(function ($route) use ($settings) {
+                if (count($route['cleanBodyParameters']) && !isset($route['headers']['Content-Type'])) {
+                    // Set content type if the user forgot to set it
+                    $route['headers']['Content-Type'] = 'application/json';
+                }
+                $route['output'] = (string)view('apidoc::partials.route')
+                    ->with('route', $route)
+                    ->with('settings', $settings)
+                    ->with('baseUrl', $this->baseUrl)
+                    ->render();
+
+                return $route;
+            });
+        });
+        return $parsedRouteOutput;
+}
 }

+ 13 - 12
tests/GenerateDocumentationTest.php

@@ -38,6 +38,7 @@ class GenerateDocumentationTest extends TestCase
     public function tearDown(): void
     {
         Utils::deleteDirectoryAndContents('/public/docs');
+        Utils::deleteDirectoryAndContents('/resources/docs');
     }
 
     /**
@@ -128,7 +129,7 @@ class GenerateDocumentationTest extends TestCase
         $this->artisan('apidoc:generate');
 
         $fixtureMarkdown = __DIR__.'/Fixtures/resource_index.md';
-        $generatedMarkdown = __DIR__.'/../public/docs/source/index.md';
+        $generatedMarkdown = __DIR__.'/../resources/docs/source/index.md';
         $this->assertFilesHaveSameContent($fixtureMarkdown, $generatedMarkdown);
     }
 
@@ -156,7 +157,7 @@ class GenerateDocumentationTest extends TestCase
         $this->artisan('apidoc:generate');
 
         $fixtureMarkdown = __DIR__.'/Fixtures/partial_resource_index.md';
-        $generatedMarkdown = __DIR__.'/../public/docs/source/index.md';
+        $generatedMarkdown = __DIR__.'/../resources/docs/source/index.md';
         $this->assertFilesHaveSameContent($fixtureMarkdown, $generatedMarkdown);
 
         if (version_compare(App::version(), '5.6', '<')) {
@@ -172,7 +173,7 @@ class GenerateDocumentationTest extends TestCase
         $this->artisan('apidoc:generate');
 
         $fixtureMarkdown = __DIR__.'/Fixtures/partial_resource_index.md';
-        $generatedMarkdown = __DIR__.'/../public/docs/source/index.md';
+        $generatedMarkdown = __DIR__.'/../resources/docs/source/index.md';
         $this->assertFilesHaveSameContent($fixtureMarkdown, $generatedMarkdown);
     }
 
@@ -202,8 +203,8 @@ class GenerateDocumentationTest extends TestCase
         ]);
         $this->artisan('apidoc:generate');
 
-        $generatedMarkdown = __DIR__.'/../public/docs/source/index.md';
-        $compareMarkdown = __DIR__.'/../public/docs/source/.compare.md';
+        $generatedMarkdown = __DIR__.'/../resources/docs/source/index.md';
+        $compareMarkdown = __DIR__.'/../resources/docs/source/.compare.md';
         $fixtureMarkdown = __DIR__.'/Fixtures/index.md';
 
         $this->assertFilesHaveSameContent($fixtureMarkdown, $generatedMarkdown);
@@ -221,12 +222,12 @@ class GenerateDocumentationTest extends TestCase
 
         $prependMarkdown = __DIR__.'/Fixtures/prepend.md';
         $appendMarkdown = __DIR__.'/Fixtures/append.md';
-        copy($prependMarkdown, __DIR__.'/../public/docs/source/prepend.md');
-        copy($appendMarkdown, __DIR__.'/../public/docs/source/append.md');
+        copy($prependMarkdown, __DIR__.'/../resources/docs/source/prepend.md');
+        copy($appendMarkdown, __DIR__.'/../resources/docs/source/append.md');
 
         $this->artisan('apidoc:generate');
 
-        $generatedMarkdown = __DIR__.'/../public/docs/source/index.md';
+        $generatedMarkdown = __DIR__.'/../resources/docs/source/index.md';
         $this->assertContainsIgnoringWhitespace($this->getFileContents($prependMarkdown), $this->getFileContents($generatedMarkdown));
         $this->assertContainsIgnoringWhitespace($this->getFileContents($appendMarkdown), $this->getFileContents($generatedMarkdown));
     }
@@ -380,7 +381,7 @@ class GenerateDocumentationTest extends TestCase
         ]);
         $this->artisan('apidoc:generate');
 
-        $generatedMarkdown = $this->getFileContents(__DIR__.'/../public/docs/source/index.md');
+        $generatedMarkdown = $this->getFileContents(__DIR__.'/../resources/docs/source/index.md');
         $this->assertContainsIgnoringWhitespace('"Authorization": "customAuthToken","Custom-Header":"NotSoCustom"', $generatedMarkdown);
     }
 
@@ -392,7 +393,7 @@ class GenerateDocumentationTest extends TestCase
         config(['apidoc.routes.0.prefixes' => ['api/*']]);
         $this->artisan('apidoc:generate');
 
-        $generatedMarkdown = file_get_contents(__DIR__.'/../public/docs/source/index.md');
+        $generatedMarkdown = file_get_contents(__DIR__.'/../resources/docs/source/index.md');
         $this->assertContains('Лорем ипсум долор сит амет', $generatedMarkdown);
     }
 
@@ -406,7 +407,7 @@ class GenerateDocumentationTest extends TestCase
 
         config(['apidoc.routes.0.prefixes' => ['api/*']]);
         $this->artisan('apidoc:generate');
-        $generatedMarkdown = file_get_contents(__DIR__.'/../public/docs/source/index.md');
+        $generatedMarkdown = file_get_contents(__DIR__.'/../resources/docs/source/index.md');
 
         $firstGroup1Occurrence = strpos($generatedMarkdown, '#1. Group 1');
         $firstGroup2Occurrence = strpos($generatedMarkdown, '#2. Group 2');
@@ -437,7 +438,7 @@ class GenerateDocumentationTest extends TestCase
         }
 
         $this->assertNull($thrownException);
-        $generatedMarkdown = file_get_contents(__DIR__.'/../public/docs/source/index.md');
+        $generatedMarkdown = file_get_contents(__DIR__.'/../resources/docs/source/index.md');
         $this->assertContains('Group A', $generatedMarkdown);
         $this->assertContains('Group B', $generatedMarkdown);
     }