Completed
Push — 42-formatter ( cff7a4 )
by Nicolas
32:10 queued 28:41
created

Hydrate::parseOptionWithAssignments()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 35
rs 8.439
cc 5
eloc 17
nc 8
nop 2
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::REQUIRED, '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
        $this->output->writeln(sprintf(
67
            "<info>Hydrate <comment>%s</comment> with <comment>%s</comment> values</info>",
68
            $input->getArgument('sourcePath'),
69
            $this->environment
70
        ));
71
        
72
        if($input->getOption('dry-run'))
73
        {
74
            $this->dryRun = true;
75
            $this->output->writeln("<fg=cyan>Run in dry-run mode</fg=cyan>");
76
        }
77
        
78
        if($input->getOption('backup'))
79
        {
80
            $this->isBackupEnabled = true;
81
            $this->output->writeln("<fg=cyan>Backup enabled</fg=cyan>");
82
        }
83
        
84
        $this->output->writeln('');
85
        
86
        $this->app['sources.path'] = $input->getArgument('sourcePath');
87
        
88
        $this->processOverridenVariables(
89
            $this->parseOptionWithAssignments($input, 'override')
90
        );
91
        $this->processCustomData(
92
            $this->parseOptionWithAssignments($input, 'data')
93
        );
94
    }
95
    
96
    private function launchHydration()
97
    {
98
        $hydrator = $this->app['hydrator'];
99
        
100
        if($this->dryRun === true)
101
        {
102
            $hydrator->setDryRun();
103
        }
104
        
105
        if($this->isBackupEnabled === true)
106
        {
107
            $hydrator->enableBackup();
108
        }
109
            
110
        $hydrator->hydrate($this->environment);
111
    }
112
    
113
    private function parseOptionWithAssignments(InputInterface $input, $optionName)
114
    {
115
        $strings = $input->getOption($optionName);
116
117
        if(! is_array($strings))
118
        {
119
            $strings = array($strings);
120
        }
121
        
122
        $data = array();
123
        
124
        foreach($strings as $string)
125
        {
126
            if(stripos($string, self::OPTION_ASSIGNMENT) === false)
127
            {
128
                throw new \InvalidArgumentException(sprintf(
129
                    '%s option must contain %c : --%s <variable>=<value>',
130
                    $optionName,
131
                    self::OPTION_ASSIGNMENT,
132
                    $optionName                        
133
                ));    
134
            }
135
136
            list($variable, $value) = explode(self::OPTION_ASSIGNMENT, $string, 2);
137
            
138
            if(array_key_exists($variable, $data))
139
            {
140
                throw new \InvalidArgumentException("Duplicated %s option value : $variable");    
141
            }
142
            
143
            $data[$variable] = $value;
144
        }
145
146
        return $data;
147
    }
148
    
149 View Code Duplication
    private function processOverridenVariables(array $overrides)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
150
    {
151
        $reader = $this->app['configuration'];
152
        $logger = $this->app['logger'];
153
154
        foreach($overrides as $variable => $value)
155
        {
156
            $logger->info(sprintf(
157
               'Override <important>%s</important> with value <important>%s</important>',
158
               $variable,
159
               $value
160
            ));
161
            
162
            $reader->overrideVariable($variable, $this->filterValue($value));
163
        }
164
    }
165
    
166 View Code Duplication
    private function processCustomData(array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
167
    {
168
        $reader = $this->app['configuration'];
169
        $logger = $this->app['logger'];
170
171
        foreach($data as $variable => $value)
172
        {
173
            $logger->info(sprintf(
174
               'Set custom data <important>%s</important> with value <important>%s</important>',
175
               $variable,
176
               $value
177
            ));
178
            
179
            $reader->setCustomData($variable, $this->filterValue($value));
180
        }
181
    }
182
}