Test Failed
Push — feature-laravel-5.4 ( 2b4b90...5bfdc4 )
by Kirill
03:52
created

GitHubDocsImport   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
dl 0
loc 148
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 22 2
A getDocsCurrentState() 0 8 1
A getFilesForSync() 0 14 2
B sync() 0 34 4
A getDocsModel() 0 10 1
1
<?php
2
3
/**
4
 * This file is part of laravel.su package.
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types = 1);
9
10
namespace App\Console\Commands;
11
12
use App\Models\Docs;
13
use App\Services\GitHub\DocsCollection;
14
use Illuminate\Support\Str;
15
use Illuminate\Console\Command;
16
use Illuminate\Support\Collection;
17
use App\Services\GitHub\DocsStatus;
18
use App\Services\GitHub\ExternalDocsPage;
19
use App\Services\GitHub\GitHubDocsManager;
20
use App\Services\GitHub\GitHubConfigRepository;
21
22
/**
23
 * Class GitHubDocsImport.
24
 */
25
class GitHubDocsImport extends Command
26
{
27
    /**
28
     * The name and signature of the console command.
29
     *
30
     * @var string
31
     */
32
    protected $signature = 'docs:import {?--force}';
33
34
    /**
35
     * The console command description.
36
     *
37
     * @var string
38
     */
39
    protected $description = 'Import documentation from GitHub.';
40
41
    /**
42
     * Execute the console command.
43
     *
44
     * @param  GitHubDocsManager      $manager
45
     * @param  GitHubConfigRepository $config
46
     * @return void
47
     * @throws \Github\Exception\ErrorException
48
     * @throws \Github\Exception\InvalidArgumentException
49
     * @throws \RuntimeException
50
     */
51
    public function handle(GitHubDocsManager $manager, GitHubConfigRepository $config): void
52
    {
53
        $exists = $this->getDocsCurrentState(...$config->values());
0 ignored issues
show
Bug introduced by
The call to getDocsCurrentState() misses some required arguments starting with $repo.
Loading history...
Documentation introduced by
$config->values() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
54
55
        $files = $this->getFilesForSync($manager, $config, $exists);
0 ignored issues
show
Bug introduced by
It seems like $exists defined by $this->getDocsCurrentState(...$config->values()) on line 53 can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, App\Console\Commands\Git...port::getFilesForSync() does only seem to accept object<Illuminate\Support\Collection>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
56
57
        if (count($files) === 0) {
58
            $this->info('Skipping: Documentation are actual.');
59
        } else {
60
            $this->info('Found ' . count($files) . ' new pages.');
61
            $this->info('Start sync progress...');
62
63
            $this->output->progressStart(count($files));
64
65
            $this->sync($files, $manager, $config);
0 ignored issues
show
Compatibility introduced by
$files of type object<Illuminate\Support\Collection> is not a sub-type of object<App\Services\GitHub\DocsCollection>. It seems like you assume a child class of the class Illuminate\Support\Collection to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
66
67
            $this->output->progressFinish();
68
        }
69
70
        $this->info('Completed');
71
        $this->output->newLine();
72
    }
73
74
    /**
75
     * @param  string $org
76
     * @param  string $repo
77
     * @param  string $branch
78
     * @return Collection
79
     */
80
    private function getDocsCurrentState(string $org, string $repo, string $branch)
81
    {
82
        return Docs::query()
83
            ->where('github_org', $org)
84
            ->where('github_repo', $repo)
85
            ->where('github_branch', $branch)
86
            ->get(['github_hash']);
87
    }
88
89
    /**
90
     * @param GitHubDocsManager      $manager
91
     * @param GitHubConfigRepository $config
92
     * @param Collection             $exists
93
     * @return Collection|DocsCollection
94
     * @throws \Github\Exception\ErrorException
95
     * @throws \Github\Exception\InvalidArgumentException
96
     * @throws \RuntimeException
97
     */
98
    private function getFilesForSync(GitHubDocsManager $manager, GitHubConfigRepository $config, Collection $exists)
99
    {
100
        $isForce = $this->option('force');
101
102
        return $manager->findFiles(...$config->values())
0 ignored issues
show
Bug introduced by
The call to findFiles() misses some required arguments starting with $repo.
Loading history...
Documentation introduced by
$config->values() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
103
            // Remove not updated docs
104
            ->reject(function (DocsStatus $status) use ($exists, $isForce) {
105
                if ($isForce) {
106
                    return false;
107
                }
108
109
                return $exists->where('github_hash', $status->getHash())->first();
110
            });
111
    }
112
113
    /**
114
     * @param DocsCollection         $files
115
     * @param GitHubDocsManager      $manager
116
     * @param GitHubConfigRepository $config
117
     * @throws \Github\Exception\ErrorException
118
     * @throws \Github\Exception\InvalidArgumentException
119
     */
120
    private function sync(DocsCollection $files, GitHubDocsManager $manager, GitHubConfigRepository $config): void
121
    {
122
        /** @var DocsStatus $status */
123
        foreach ($files as $status) {
124
            $args = $config->values();
125
            $args[] = $status->getPath();
126
127
            /** @var ExternalDocsPage $page */
128
            $page = $manager->import(...$args);
0 ignored issues
show
Bug introduced by
The call to import() misses some required arguments starting with $repo.
Loading history...
Documentation introduced by
$args is of type array<integer,?>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
129
130
            $docs = $this->getDocsModel(...$args);
0 ignored issues
show
Bug introduced by
The call to getDocsModel() misses some required arguments starting with $repo.
Loading history...
Documentation introduced by
$args is of type array<integer,?>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
131
132
            $docs->content_source = $page->getContent();
133
            $docs->github_hash = $status->getHash();
134
135
            if (! $docs->category_id) {
136
                $docs->category_id = 0; // TODO
137
            }
138
139
140
            if (! $docs->title) {
141
                $docs->title = Str::ucfirst(str_replace(
142
                    ['-', '_'],
143
                    ' ',
144
                    $page->getUrl()
145
                ));
146
            }
147
148
            $docs->save();
149
150
            $this->output->progressAdvance();
151
            $this->output->write(sprintf(' <info>Synchronizing "%s" page</info>', $docs->title));
152
        }
153
    }
154
155
    /**
156
     * @param  string $org
157
     * @param  string $repo
158
     * @param  string $branch
159
     * @param  string $file
160
     * @return \Illuminate\Database\Eloquent\Model|Docs
161
     */
162
    private function getDocsModel(string $org, string $repo, string $branch, string $file)
163
    {
164
        return Docs::query()
165
            ->firstOrNew([
166
                'github_org'    => $org,
167
                'github_repo'   => $repo,
168
                'github_branch' => $branch,
169
                'github_file'   => $file,
170
            ]);
171
    }
172
}
173