Completed
Push — master ( d24520...9dfa2d )
by Nicolas
05:12
created

ConfigureActionCommand::processInputs()   C

Complexity

Conditions 9
Paths 52

Size

Total Lines 64
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 3 Features 1
Metric Value
c 5
b 3
f 1
dl 0
loc 64
rs 6.5449
cc 9
eloc 34
nc 52
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Karma\Command;
4
5
use Symfony\Component\Console\Input\InputArgument;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Karma\Application;
10
use Karma\Command;
11
use Karma\Configuration\FilterInputVariable;
12
use Karma\ConfigurableProcessor;
13
14
abstract class ConfigureActionCommand extends Command
15
{
16
    use FilterInputVariable;
17
18
    const
19
        ENV_DEV = 'dev',
20
        OPTION_ASSIGNMENT = '=';
21
22
    private
23
        $dryRun,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
24
        $isBackupEnabled,
25
        $systemEnvironment,
26
        $name,
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
27
        $description,
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
28
        $outputTitle;
29
30
    protected
31
        $environment;
32
33
    public function __construct(Application $app, $name, $description, $outputTitle)
34
    {
35
        $this->name = $name;
36
        $this->description = $description;
37
        $this->outputTitle = $outputTitle;
38
39
        parent::__construct($app);
40
41
        $this->dryRun = false;
42
        $this->isBackupEnabled = false;
43
44
        $this->environment = self::ENV_DEV;
45
        $this->systemEnvironment = null;
46
    }
47
48
    protected function configure()
49
    {
50
        parent::configure();
51
52
        $this
53
            ->setName($this->name)
54
            ->setDescription($this->description)
55
56
            ->addArgument('sourcePath', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'source path to hydrate/generate')
57
58
            ->addOption('targetPath', 't', InputOption::VALUE_REQUIRED, 'target path to hydrate/generate', null)
59
            ->addOption('env', 'e', InputOption::VALUE_REQUIRED, 'Target environment', self::ENV_DEV)
60
            ->addOption('system', 's', InputOption::VALUE_REQUIRED, 'Target environment for system variables', null)
61
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Simulation mode')
62
            ->addOption('backup', 'b', InputOption::VALUE_NONE, 'Backup overwritten files')
63
            ->addOption('override', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Override variable values', array())
64
            ->addOption('data', 'd', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Custom data values', array())
65
        ;
66
    }
67
68
    protected function execute(InputInterface $input, OutputInterface $output)
69
    {
70
        parent::execute($input, $output);
71
72
        $this->processInputs($input);
73
74
        $processor = $this->getProcessor();
75
        $this->configureProcessor($processor);
76
        $this->launchConfigurationAction($processor);
77
    }
78
79
    private function processInputs(InputInterface $input)
80
    {
81
        $this->environment = $input->getOption('env');
82
        $this->systemEnvironment = $input->getOption('system');
83
84
        if($input->getOption('dry-run'))
85
        {
86
            $this->dryRun = true;
87
            $this->output->writeln("<fg=cyan>Run in dry-run mode</fg=cyan>");
88
        }
89
90
        if($input->getOption('backup'))
91
        {
92
            $this->isBackupEnabled = true;
93
            $this->output->writeln("<fg=cyan>Backup enabled</fg=cyan>");
94
        }
95
96
        $profile = $this->app['profile'];
97
        $sourcePath = $input->getArgument('sourcePath');
98
        if(empty($sourcePath))
99
        {
100
            if($profile->hasSourcePath() !== true)
101
            {
102
                throw new \RuntimeException('Missing argument sourcePath');
103
            }
104
105
            $sourcePath = $profile->getSourcePath();
106
        }
107
108
        if(! is_array($sourcePath))
109
        {
110
            $sourcePath = array($sourcePath);
111
        }
112
113
        $targetPath = $input->getOption('targetPath');
114
115
        if(is_array($targetPath))
116
        {
117
            throw new \RuntimeException('Invalid argument targetPath : could not be mutiple (single path required as string)');
118
        }
119
120
        if(empty($targetPath) && $profile->hasTargetPath() === true)
121
        {
122
            $targetPath = $profile->getTargetPath();
123
        }
124
125
        $this->output->writeln(sprintf(
126
            "<info>%s <comment>%s</comment> with <comment>%s</comment> values</info>",
127
            $this->outputTitle,
128
            implode(' ', $sourcePath),
129
            $this->environment
130
        ));
131
        $this->output->writeln('');
132
133
        $this->app['sources.path'] = $sourcePath;
134
        $this->app['target.path'] = $targetPath;
135
136
        $this->processOverridenVariables(
137
            $this->parseOptionWithAssignments($input, 'override')
138
        );
139
        $this->processCustomData(
140
            $this->parseOptionWithAssignments($input, 'data')
141
        );
142
    }
143
144
    abstract protected function launchConfigurationAction(ConfigurableProcessor $processor);
145
    abstract protected function getProcessor();
146
147
    private function configureProcessor(ConfigurableProcessor $processor)
148
    {
149
        if($this->dryRun === true)
150
        {
151
            $processor->setDryRun();
152
        }
153
154
        if($this->isBackupEnabled === true)
155
        {
156
            $processor->enableBackup();
157
        }
158
159
        if($this->systemEnvironment !== null)
160
        {
161
            $processor->setSystemEnvironment($this->systemEnvironment);
162
163
             $this->app['logger']->info(sprintf(
164
                'Hydrate <important>system</important> variables with <important>%s</important> values',
165
                $this->systemEnvironment
166
            ));
167
        }
168
    }
169
170
    private function parseOptionWithAssignments(InputInterface $input, $optionName)
171
    {
172
        $strings = $input->getOption($optionName);
173
174
        if(! is_array($strings))
175
        {
176
            $strings = array($strings);
177
        }
178
179
        $data = array();
180
181
        foreach($strings as $string)
182
        {
183
            if(stripos($string, self::OPTION_ASSIGNMENT) === false)
184
            {
185
                throw new \InvalidArgumentException(sprintf(
186
                    '%s option must contain %c : --%s <variable>=<value>',
187
                    $optionName,
188
                    self::OPTION_ASSIGNMENT,
189
                    $optionName
190
                ));
191
            }
192
193
            list($variable, $value) = explode(self::OPTION_ASSIGNMENT, $string, 2);
194
195
            if(array_key_exists($variable, $data))
196
            {
197
                throw new \InvalidArgumentException("Duplicated %s option value : $variable");
198
            }
199
200
            $data[$variable] = $value;
201
        }
202
203
        return $data;
204
    }
205
206
    private function processOverridenVariables(array $overrides)
207
    {
208
        $reader = $this->app['configuration'];
209
        $logger = $this->app['logger'];
210
211
        foreach($overrides as $variable => $value)
212
        {
213
            $logger->info(sprintf(
214
               'Override <important>%s</important> with value <important>%s</important>',
215
               $variable,
216
               $value
217
            ));
218
219
            $value = $this->parseList($value);
220
221
            $reader->overrideVariable($variable, $this->filterValue($value));
222
        }
223
    }
224
225
    private function processCustomData(array $data)
226
    {
227
        $reader = $this->app['configuration'];
228
        $logger = $this->app['logger'];
229
230
        foreach($data as $variable => $value)
231
        {
232
            $logger->info(sprintf(
233
               'Set custom data <important>%s</important> with value <important>%s</important>',
234
               $variable,
235
               $value
236
            ));
237
238
            $reader->setCustomData($variable, $this->filterValue($value));
239
        }
240
    }
241
}
242