BaseCommand::getResultState()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
ccs 0
cts 0
cp 0
nc 1
1
<?php
2
3
  namespace Funivan\Cs\Console;
4
5
  use Funivan\Cs\Configuration\ConfigurationInterface;
6
  use Funivan\Cs\FileProcessor\BaseFileProcessor;
7
  use Funivan\Cs\FileProcessor\FileProcessorInterface;
8
  use Funivan\Cs\FileTool\ToolsFilter;
9
  use Funivan\Cs\Fs\FileFinder\FinderParameters;
10
  use Funivan\Cs\Report\Report;
11
  use Symfony\Component\Console\Command\Command;
12
  use Symfony\Component\Console\Input\InputInterface;
13
  use Symfony\Component\Console\Input\InputOption;
14
  use Symfony\Component\Console\Output\OutputInterface;
15
16
  /**
17
   * @author Ivan Shcherbak <[email protected]> 2016
18
   */
19
  abstract class BaseCommand extends Command {
20
21
    /**
22
     * @inheritDoc
23
     */
24
    protected function configure() {
25
26
      $this->addOption('configuration', null, InputOption::VALUE_REQUIRED, 'Path to the configuration file', null);
27
28
      $this->addOption('finder-parameter', null, InputOption::VALUE_IS_ARRAY ^ InputOption::VALUE_REQUIRED, 'Provide custom parameters fot the file finder', []);
29
30
      $this->addOption('filter-tools', null, InputOption::VALUE_IS_ARRAY ^ InputOption::VALUE_REQUIRED, 'Filter tools by name', []);
31
32
      #
33
      $this->addOption('list-tools', null, InputOption::VALUE_NONE, 'Show Tools that will be applied to the files');
34
      $this->addOption('list-all-tools', null, InputOption::VALUE_NONE, 'Show All Tools that can be used');
35
36
37
      parent::configure();
38
    }
39
40
41
    /**
42
     * @inheritdoc
43
     */
44
    protected final function execute(InputInterface $input, OutputInterface $output) {
45
46
      $config = $this->createConfiguration($input->getOption('configuration'));
47
48
      $tools = $config->getTools();
49
50
      # list all tools
51
      if ($input->getOption('list-all-tools')) {
52
        foreach ($tools as $tool) {
53
          $output->writeln('Tool : ' . $tool->getName());
54
        }
55
        return 0;
56
      }
57
58
      $toolsFilter = $this->createToolsFilter($input->getOption('filter-tools'));
59
60
      foreach ($tools as $index => $tool) {
61
        if (!$toolsFilter->isValid($tool)) {
62
          unset($tools[$index]);
63
        }
64
      }
65
66
      # list tools
67
      if ($input->getOption('list-tools')) {
68
        foreach ($tools as $tool) {
69
          $output->writeln('Tool : ' . $tool->getName());
70
        }
71
        return 0;
72
      }
73
74
      $fileProcessor = $this->getFileProcessor($input, $output);
75
      foreach ($tools as $tool) {
76
        $fileProcessor->addTool($tool);
77
        $output->writeln('Add tool: ' . $tool->getName(), OutputInterface::VERBOSITY_VERY_VERBOSE);
78
      }
79
80
      if ($fileProcessor instanceof BaseFileProcessor) {
81
        $fileProcessor->setOutput($output);
82
      }
83
84
85
      $parameters = $input->getOption('finder-parameter');
86
      $finderParameters = $this->createFinderParameters($parameters);
87
88
      $files = $config->getFilesFinder()->findFiles($finderParameters);
89
90
91
      if ($files->count() === 0) {
92
        $output->writeln('<comment>✔ Empty files list</comment>');
93
        return 0;
94
      }
95
96
      $report = new Report();
97
98
      $fileProcessor->process($files, $report);
99
100
      return $this->getResultState($input, $output, $report);
101
    }
102
103
104
    /**
105
     * @param InputInterface $input
106
     * @param OutputInterface $output
107
     * @return FileProcessorInterface
108
     */
109
    protected abstract function getFileProcessor(InputInterface $input, OutputInterface $output);
110
111
112
    /**
113
     * @param InputInterface $input
114
     * @param OutputInterface $output
115
     * @param Report $report
116
     * @return int
117
     */
118
    protected abstract function getResultState(InputInterface $input, OutputInterface $output, Report $report);
119
120
121
    /**
122
     * @return ConfigurationInterface
123
     */
124
    protected abstract function getDefaultConfiguration();
125
126
127
    /**
128
     * @param array $rawParameters
129
     * @return FinderParameters
130
     */
131
    private function createFinderParameters(array $rawParameters) {
132
      $finderParameters = new FinderParameters();
133
134
      /** @var Application $app */
135
      $app = $this->getApplication();
136
137
      $finderParameters->set('baseDir', $app->getBaseProjectDirectory());
138
      foreach ($rawParameters as $paramInfo) {
139
        $finderParameter = explode(':', $paramInfo);
140
        if (count($finderParameter) !== 2) {
141
          throw new \InvalidArgumentException('Invalid params format. Expect 2 values');
142
        }
143
        $finderParameters->set($finderParameter[0], $finderParameter[1]);
144
      }
145
146
      return $finderParameters;
147
    }
148
149
150
    /**
151
     * @param string|null $configurationFilePath
152
     * @return ConfigurationInterface
153
     * @throws \Exception
154
     */
155
    protected function createConfiguration($configurationFilePath) {
156
      if ($configurationFilePath === null) {
157
        return $this->getDefaultConfiguration();
158
      }
159
160
      /** @noinspection PhpIncludeInspection */
161
      /** @var ConfigurationInterface $config */
162
      $config = include_once $configurationFilePath;
163
164
      if (empty($config)) {
165
        throw new \Exception('Provide valid configuration file path');
166
      }
167
168
      if (!($config instanceof ConfigurationInterface)) {
169
        throw new \Exception('Invalid configuration file result. Expect ' . ConfigurationInterface::class);
170
      }
171
172
      return $config;
173
    }
174
175
176
    /**
177
     * @param string[] $filters
178
     * @return ToolsFilter
179
     */
180
    protected function createToolsFilter(array $filters) {
181
182
      $include = null;
183
      $exclude = null;
184
185
186
      $fixerNames = explode(',', implode(',', $filters));
187
      $fixerNames = array_map('trim', $fixerNames);
188
      $fixerNames = array_filter($fixerNames);
189
190
      foreach ($fixerNames as $name) {
191
        if (strpos($name, '-') === 0) {
192
          $exclude[] = (string) substr($name, 1);
193
        } else {
194
          $include[] = (string) $name;
195
        }
196
      }
197
198
199
      $toolsFilter = new ToolsFilter();
200
      $toolsFilter->setExclude($exclude);
201
      $toolsFilter->setInclude($include);
202
203
      return $toolsFilter;
204
    }
205
206
  }