GenerateDocumentation   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 41
dl 0
loc 117
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 13 2
B processRoutes() 0 38 8
A getRoutes() 0 5 1
A writeAll() 0 11 2
1
<?php
2
3
namespace AlexWells\ApiDocsGenerator\Commands;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\Route;
7
use AlexWells\ApiDocsGenerator\Parsers\RouteWrapper;
8
use AlexWells\ApiDocsGenerator\Postman\CollectionGenerator;
9
use AlexWells\ApiDocsGenerator\Exceptions\RouteGenerationError;
10
11
class GenerateDocumentation extends BaseCommand
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'api-docs:generate
19
                            {--o|output=public/docs : The output path for the generated documentation}
20
                            {--m|masks=* : Route masks to check}
21
                            {--noPostmanGeneration : Disable Postman collection generation}
22
                            {--noTypeChecks : Skip \'no type specified\' parameter exceptions}
23
                            {--traces : Show full exception traces (non-standard only)}
24
    ';
25
26
    /**
27
     * The console command description.
28
     *
29
     * @var string
30
     */
31
    protected $description = 'Generate your API documentation from existing Laravel routes.';
32
33
    /**
34
     * Execute the console command.
35
     *
36
     * @return void
37
     */
38
    public function handle()
39
    {
40
        $this->addStyles();
41
42
        if (! count($this->option('masks'))) {
43
            $this->error('You must provide at least one route mask.');
44
45
            return;
46
        }
47
48
        $parsedRoutes = $this->processRoutes();
49
50
        $this->writeAll($parsedRoutes);
0 ignored issues
show
Bug introduced by
$parsedRoutes of type array<mixed,array> is incompatible with the type AlexWells\ApiDocsGenerator\Parsers\RouteWrapper[] expected by parameter $parsedRoutes of AlexWells\ApiDocsGenerat...cumentation::writeAll(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
        $this->writeAll(/** @scrutinizer ignore-type */ $parsedRoutes);
Loading history...
51
    }
52
53
    /**
54
     * Process routes.
55
     *
56
     * @return array[]
57
     */
58
    private function processRoutes()
59
    {
60
        $parsedRoutes = [];
61
62
        foreach ($this->getRoutes() as $route) {
63
            $label = '<red>[' . implode(',', $route->getMethods()) . '] ' . $route->getUri() . ' at ' . $route->getActionSafe() . '</red>';
64
65
            $this->overwrite("Processing route $label", 'info');
66
67
            if(
68
                // Does this route match route mask
69
                ! $route->matchesAnyMask($this->option('masks')) ||
70
                // Is it valid
71
                ! $route->isSupported() ||
72
                // Should it be skipped
73
                $route->isHiddenFromDocs()
74
            ) {
75
                $this->overwrite("Skipping route $label", 'warn');
76
                continue;
77
            }
78
79
            try {
80
                $parsedRoutes[] = $route->getSummary();
81
                $this->overwrite("Processed route $label", 'info');
82
            } catch (RouteGenerationError $exception) {
83
                $this->output->writeln('');
84
                $this->warn($exception->getMessage());
85
            } catch (\Exception $exception) {
86
                $this->output->writeln('');
87
                $exceptionStr = $this->option('traces') ? $exception : $exception->getMessage();
88
                $this->error('Failed to process: ' . $exceptionStr);
89
                continue;
90
            }
91
            $this->info('');
92
        }
93
        $this->info('');
94
95
        return $parsedRoutes;
96
    }
97
98
    /**
99
     * Get all routes wrapped in helper class.
100
     *
101
     * @return RouteWrapper[]
102
     */
103
    private function getRoutes()
104
    {
105
        return array_map(function ($route) {
106
            return new RouteWrapper($route, $this->options());
107
        }, Route::getRoutes()->get());
108
    }
109
110
    /**
111
     * Writes parsed routes into everything needed (html, postman collection).
112
     *
113
     * @param  RouteWrapper[] $parsedRoutes
114
     *
115
     * @return void
116
     */
117
    private function writeAll($parsedRoutes)
118
    {
119
        $outputPath = $this->option('output');
120
121
        if(! is_dir($outputPath)) {
122
            mkdir($outputPath, 0777, true);
123
        }
124
125
        $documentation = view('api-docs::documentation', compact('parsedRoutes'));
126
127
        file_put_contents($outputPath . DIRECTORY_SEPARATOR . 'index.html', $documentation);
128
129
        // broken :(
130
        /*if ($this->option('noPostmanGeneration') !== true) {
131
            $collection = (new CollectionGenerator($parsedRoutes))->getCollection();
132
133
            file_put_contents($outputPath . DIRECTORY_SEPARATOR . 'collection.json', $collection);
134
        }*/
135
    }
136
}
137