Completed
Push — 57-formatter-per-extension ( 73b3c8 )
by Nicolas
40:17 queued 36:16
created

Hydrate::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 5
Metric Value
c 7
b 0
f 5
dl 0
loc 17
rs 9.4286
cc 1
eloc 11
nc 1
nop 0
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
13
class Hydrate extends Command
14
{
15
    use FilterInputVariable;
16
    
17
    const
18
        ENV_DEV = 'dev',
19
        OPTION_ASSIGNMENT = '=';
20
    
21
    private
22
        $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...
23
        $isBackupEnabled,
24
        $environment;
25
    
26
    public function __construct(Application $app)
27
    {
28
        parent::__construct($app);
29
        
30
        $this->dryRun = false;
31
        $this->isBackupEnabled = false;
32
        
33
        $this->environment = self::ENV_DEV;
34
    }
35
    
36
    protected function configure()
37
    {
38
        parent::configure();
39
        
40
        $this
41
            ->setName('hydrate')
42
            ->setDescription('Hydrate dist files')
43
            
44
            ->addArgument('sourcePath', InputArgument::OPTIONAL, 'source path to hydrate')
45
            
46
            ->addOption('env', 'e', InputOption::VALUE_REQUIRED, 'Target environment', self::ENV_DEV)
47
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Simulation mode')
48
            ->addOption('backup', 'b', InputOption::VALUE_NONE, 'Backup overwritten files')
49
            ->addOption('override', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Override variable values', array())
50
            ->addOption('data', 'd', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Custom data values', array())
51
        ;
52
    }
53
    
54
    protected function execute(InputInterface $input, OutputInterface $output)
55
    {
56
        parent::execute($input, $output);
57
        
58
        $this->processInputs($input);
59
        $this->launchHydration();
60
    }
61
    
62
    private function processInputs(InputInterface $input)
63
    {
64
        $this->environment = $input->getOption('env'); 
65
        
66
        if($input->getOption('dry-run'))
67
        {
68
            $this->dryRun = true;
69
            $this->output->writeln("<fg=cyan>Run in dry-run mode</fg=cyan>");
70
        }
71
        
72
        if($input->getOption('backup'))
73
        {
74
            $this->isBackupEnabled = true;
75
            $this->output->writeln("<fg=cyan>Backup enabled</fg=cyan>");
76
        }
77
        
78
        $sourcePath = $input->getArgument('sourcePath');
79 View Code Duplication
        if($sourcePath === null)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
80
        {
81
            $profile = $this->app['profile'];
82
            if($profile->hasSourcePath() !== true)
83
            {
84
                throw new \RuntimeException('Missing argument sourcePath');
85
            }
86
            
87
            $sourcePath = $profile->getSourcePath();
88
        }
89
        
90
        $this->output->writeln(sprintf(
91
            "<info>Hydrate <comment>%s</comment> with <comment>%s</comment> values</info>",
92
            $sourcePath,
93
            $this->environment
94
        ));
95
        $this->output->writeln('');
96
        
97
        $this->app['sources.path'] = $sourcePath;
98
        
99
        $this->processOverridenVariables(
100
            $this->parseOptionWithAssignments($input, 'override')
101
        );
102
        $this->processCustomData(
103
            $this->parseOptionWithAssignments($input, 'data')
104
        );
105
    }
106
    
107
    private function launchHydration()
108
    {
109
        $hydrator = $this->app['hydrator'];
110
        
111
        if($this->dryRun === true)
112
        {
113
            $hydrator->setDryRun();
114
        }
115
        
116
        if($this->isBackupEnabled === true)
117
        {
118
            $hydrator->enableBackup();
119
        }
120
            
121
        $hydrator->hydrate($this->environment);
122
    }
123
    
124
    private function parseOptionWithAssignments(InputInterface $input, $optionName)
125
    {
126
        $strings = $input->getOption($optionName);
127
128
        if(! is_array($strings))
129
        {
130
            $strings = array($strings);
131
        }
132
        
133
        $data = array();
134
        
135
        foreach($strings as $string)
136
        {
137
            if(stripos($string, self::OPTION_ASSIGNMENT) === false)
138
            {
139
                throw new \InvalidArgumentException(sprintf(
140
                    '%s option must contain %c : --%s <variable>=<value>',
141
                    $optionName,
142
                    self::OPTION_ASSIGNMENT,
143
                    $optionName                        
144
                ));    
145
            }
146
147
            list($variable, $value) = explode(self::OPTION_ASSIGNMENT, $string, 2);
148
            
149
            if(array_key_exists($variable, $data))
150
            {
151
                throw new \InvalidArgumentException("Duplicated %s option value : $variable");    
152
            }
153
            
154
            $data[$variable] = $value;
155
        }
156
157
        return $data;
158
    }
159
    
160
    private function processOverridenVariables(array $overrides)
161
    {
162
        $reader = $this->app['configuration'];
163
        $logger = $this->app['logger'];
164
165
        foreach($overrides as $variable => $value)
166
        {
167
            $logger->info(sprintf(
168
               'Override <important>%s</important> with value <important>%s</important>',
169
               $variable,
170
               $value
171
            ));
172
            
173
            $value = $this->parseList($value);
174
            
175
            $reader->overrideVariable($variable, $this->filterValue($value));
176
        }
177
    }
178
    
179
    private function processCustomData(array $data)
180
    {
181
        $reader = $this->app['configuration'];
182
        $logger = $this->app['logger'];
183
184
        foreach($data as $variable => $value)
185
        {
186
            $logger->info(sprintf(
187
               'Set custom data <important>%s</important> with value <important>%s</important>',
188
               $variable,
189
               $value
190
            ));
191
            
192
            $reader->setCustomData($variable, $this->filterValue($value));
193
        }
194
    }
195
}