Test Failed
Push — master ( 857c27...82742e )
by Marius
01:45
created

ConfigureCommand::getBinDirectory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Paysera\PhpStormHelper\Command;
6
7
use Paysera\PhpStormHelper\Service\ConfigurationOptionFinder;
8
use Paysera\PhpStormHelper\Service\GitignoreHelper;
9
use Paysera\PhpStormHelper\Service\SourceFolderHelper;
10
use Paysera\PhpStormHelper\Service\StructureConfigurator;
11
use Paysera\PhpStormHelper\Service\WorkspaceConfigurationHelper;
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Input\InputArgument;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
18
class ConfigureCommand extends Command
19
{
20
    private $structureConfigurator;
21
    private $gitignoreHelper;
22
    private $configurationOptionFinder;
23
    private $workspaceConfigurationHelper;
24
    private $sourceFolderHelper;
25
26
    public function __construct(
27
        StructureConfigurator $structureConfigurator,
28
        GitignoreHelper $gitignoreHelper,
29
        ConfigurationOptionFinder $configurationOptionFinder,
30
        WorkspaceConfigurationHelper $workspaceConfigurationHelper,
31
        SourceFolderHelper $sourceFolderHelper
32
    ) {
33
        parent::__construct();
34
35
        $this->structureConfigurator = $structureConfigurator;
36
        $this->gitignoreHelper = $gitignoreHelper;
37
        $this->configurationOptionFinder = $configurationOptionFinder;
38
        $this->workspaceConfigurationHelper = $workspaceConfigurationHelper;
39
        $this->sourceFolderHelper = $sourceFolderHelper;
40
    }
41
42
    protected function configure()
43
    {
44
        $this
45
            ->setName('configure')
46
            ->addArgument(
47
                'project-root-dir',
48
                InputArgument::OPTIONAL,
49
                'Default is current directory'
50
            )
51
            ->addArgument('path-to-configuration-template-structure', InputArgument::OPTIONAL)
52
            ->addOption(
53
                'update-gitignore',
54
                null,
55
                null,
56
                'Modify gitignore file – use this when you intend to version common .idea files'
57
            )
58
            ->addOption(
59
                'docker-image',
60
                null,
61
                InputOption::VALUE_OPTIONAL,
62
                <<<'DOC'
63
Docker image to use for this project. For example, php:7.3-cli or example.org/image:latest.
64
If not provided, currently configured image is maintained in the configuration.
65
DOC
66
            )
67
            ->addOption(
68
                'webpack-config-path',
69
                null,
70
                InputOption::VALUE_OPTIONAL,
71
                <<<'DOC'
72
Relative path from project root dir to webpack configuration file.
73
If not provided, currently configured path is maintained in the configuration.
74
DOC
75
            )
76
            ->addOption(
77
                'server',
78
                's',
79
                InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL,
80
                <<<'DOC'
81
Server mappings, for example my-project.docker:443@/path/in/server.
82
Server is added in the list unless one already exists with such host and post.
83
DOC
84
            )
85
        ;
86
    }
87
88
    protected function execute(InputInterface $input, OutputInterface $output)
89
    {
90
        $target = $input->getArgument('project-root-dir');
91
        if ($target === null) {
92
            $target = realpath('.');
93
        }
94
95
        $this->configureStructure($input, $target);
96
        $this->configureWorkspace($input, $target);
0 ignored issues
show
Bug introduced by
It seems like $target defined by $input->getArgument('project-root-dir') on line 90 can also be of type array<integer,string>; however, Paysera\PhpStormHelper\C...d::configureWorkspace() does only seem to accept string, 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...
97
98
        if ($input->getOption('update-gitignore')) {
99
            $this->gitignoreHelper->setupGitignore($target . '/.gitignore');
100
        }
101
102
        $output->writeln('Restart PhpStorm instance for changes to take effect');
103
    }
104
105
    /**
106
     * @param InputInterface $input
107
     * @param $target
108
     */
109
    private function configureStructure(InputInterface $input, $target)
110
    {
111
        $path = $input->getArgument('path-to-configuration-template-structure');
112
        if ($path === null) {
113
            $path = __DIR__ . '/../../config/default';
114
        }
115
116
        $composerPath = $target . '/composer.json';
117
        $options = [];
118
119
        if ($input->getOption('docker-image')) {
120
            $options['dockerImage'] = $input->getOption('docker-image');
121
        } else {
122
            $options['dockerImage'] = $this->configurationOptionFinder->findUsedDockerImage($target);
123
        }
124
125
        if ($input->getOption('webpack-config-path')) {
126
            $options['webpackConfigPath'] = $input->getOption('webpack-config-path');
127
        } else {
128
            $options['webpackConfigPath'] = $this->configurationOptionFinder->findWebpackConfigPath($target);
129
        }
130
131
        if (file_exists($target . '/.php_cs')) {
132
            $options['phpCsFixerConfigPath'] = '.php_cs';
133
            $fixerBinary = $this->checkPayseraPhpCsFixerSupport($composerPath) ? 'paysera-php-cs-fixer' : 'php-cs-fixer';
134
            $options['phpCsFixerExecutable'] = $this->getBinDirectory($composerPath) . '/' . $fixerBinary;
135
        }
136
137
        $options['symfonyEnabled'] = $this->checkSymfonySupport($composerPath);
138
139
        $options['sourceFolders'] = $this->sourceFolderHelper->getSourceFolders($target);
140
141
        $this->structureConfigurator->configure($path, $target, $options);
0 ignored issues
show
Bug introduced by
It seems like $path defined by $input->getArgument('pat...on-template-structure') on line 111 can also be of type array<integer,string>; however, Paysera\PhpStormHelper\S...nfigurator::configure() does only seem to accept string, 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...
142
    }
143
144
    private function configureWorkspace(InputInterface $input, string $target)
145
    {
146
        $pathToWorkspaceXml = $target . '/.idea/workspace.xml';
147
148
        $this->workspaceConfigurationHelper->configureComposer($pathToWorkspaceXml);
149
        $this->workspaceConfigurationHelper->configureFileTemplateScheme($pathToWorkspaceXml);
150
        $this->workspaceConfigurationHelper->setupPhpUnitRunConfiguration($pathToWorkspaceXml);
151
152
        $serverMappings = $input->getOption('server');
153
        $this->workspaceConfigurationHelper->setupServerMappings($pathToWorkspaceXml, $serverMappings);
154
    }
155
156
    private function checkSymfonySupport(string $composerPath)
157
    {
158
        return (
159
            $this->isPackageRequired($composerPath, 'symfony/symfony')
160
            || $this->isPackageRequired($composerPath, 'symfony/framework-bundle')
161
        );
162
    }
163
164
    private function checkPayseraPhpCsFixerSupport(string $composerPath)
165
    {
166
        return $this->isPackageRequired($composerPath, 'paysera/lib-php-cs-fixer-config');
167
    }
168
169
    private function getBinDirectory(string $composerPath)
170
    {
171
        return $this->parseComposer($composerPath)['config']['bin-dir'] ?? 'vendor/bin';
172
    }
173
174
    private function isPackageRequired(string $composerPath, string $package)
175
    {
176
        $composerContents = $this->parseComposer($composerPath);
177
        return isset($composerContents['require'][$package]) || isset($composerContents['require-dev'][$package]);
178
    }
179
180
    private function parseComposer(string $composerPath)
181
    {
182
        if (!file_exists($composerPath)) {
183
            return [];
184
        }
185
186
        return json_decode(file_get_contents($composerPath), true) ?: [];
187
    }
188
}
189