|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the Blast Project package. |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright (C) 2015-2017 Libre Informatique |
|
7
|
|
|
* |
|
8
|
|
|
* This file is licenced under the GNU LGPL v3. |
|
9
|
|
|
* For the full copyright and license information, please view the LICENSE.md |
|
10
|
|
|
* file that was distributed with this source code. |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
namespace Blast\Bundle\CoreBundle\Command; |
|
14
|
|
|
|
|
15
|
|
|
use DateTime; |
|
16
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
|
17
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
|
18
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
|
19
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
|
20
|
|
|
use Symfony\Component\Yaml\Yaml; |
|
21
|
|
|
|
|
22
|
|
|
class PatcherGenerateCommand extends ContainerAwareCommand |
|
23
|
|
|
{ |
|
24
|
|
|
/** |
|
25
|
|
|
* Command generates patch file [originalFilePath, modifiedPathFile, outputFilename]. |
|
26
|
|
|
* |
|
27
|
|
|
* @var string |
|
28
|
|
|
*/ |
|
29
|
|
|
private $command = 'diff -Naur %1$s %2$s > %3$s'; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @var DateTime |
|
33
|
|
|
*/ |
|
34
|
|
|
private $now; |
|
35
|
|
|
|
|
36
|
|
|
use PatcherConfig, |
|
37
|
|
|
PatcherLogger; |
|
38
|
|
|
|
|
39
|
|
|
protected function configure() |
|
40
|
|
|
{ |
|
41
|
|
|
$this |
|
42
|
|
|
->setName('blast:patchs:generate') |
|
43
|
|
|
->setDescription('Generate Patches from Librinfo on misc vendors') |
|
44
|
|
|
->addArgument( |
|
45
|
|
|
'original-file', |
|
46
|
|
|
InputArgument::REQUIRED, |
|
47
|
|
|
'The (absolute or project root relative) path to original file' |
|
48
|
|
|
) |
|
49
|
|
|
->addArgument( |
|
50
|
|
|
'modified-file', |
|
51
|
|
|
InputArgument::REQUIRED, |
|
52
|
|
|
'The (absolute or project root relative) path to modified file' |
|
53
|
|
|
)->addArgument( |
|
54
|
|
|
'target-file', |
|
55
|
|
|
InputArgument::REQUIRED, |
|
56
|
|
|
'The project root relative path to target file (the file to be patched)' |
|
57
|
|
|
); |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
61
|
|
|
{ |
|
62
|
|
|
$this->now = new DateTime('NOW'); |
|
63
|
|
|
$this->loadConfig(); |
|
64
|
|
|
|
|
65
|
|
|
$originalPath = $input->getArgument('original-file'); |
|
66
|
|
|
$modifiedPath = $input->getArgument('modified-file'); |
|
67
|
|
|
$targetPath = $input->getArgument('target-file'); |
|
68
|
|
|
|
|
69
|
|
|
if (substr($targetPath, 0, 1) == '/') { |
|
70
|
|
|
$this->error('The target-file argument must be a project root relative path'); |
|
71
|
|
|
$this->comment($targetPath); |
|
72
|
|
|
|
|
73
|
|
|
return; |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
$this->createPatch($originalPath, $modifiedPath, $targetPath); |
|
77
|
|
|
|
|
78
|
|
|
$this->displayMessages($output); |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
private function createPatch($originalPath, $modifiedPath, $targetPath) |
|
82
|
|
|
{ |
|
83
|
|
|
$this->info('Generating patches'); |
|
84
|
|
|
|
|
85
|
|
|
$modifiedPath = $this->managePath($modifiedPath, 'patched'); |
|
86
|
|
|
$originalPath = $this->managePath($originalPath, 'original'); |
|
87
|
|
|
|
|
88
|
|
View Code Duplication |
if (!file_exists($originalPath) || !file_exists($modifiedPath)) { |
|
|
|
|
|
|
89
|
|
|
$this->error('Files not found :'); |
|
90
|
|
|
if (!file_exists($originalPath)) { |
|
91
|
|
|
$this->comment(' - ' . $originalPath); |
|
92
|
|
|
} |
|
93
|
|
|
if (!file_exists($modifiedPath)) { |
|
94
|
|
|
$this->comment(' - ' . $modifiedPath); |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
return; |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
$command = sprintf( |
|
101
|
|
|
$this->command, |
|
102
|
|
|
$originalPath, |
|
103
|
|
|
$modifiedPath, |
|
104
|
|
|
$this->config['paths']['patchFilesDir'] . '/' . $this->now->getTimestamp() . '.txt' |
|
105
|
|
|
); |
|
106
|
|
|
|
|
107
|
|
|
$this->info('Executing command : '); |
|
108
|
|
|
$this->comment($command); |
|
109
|
|
|
system($command); |
|
110
|
|
|
|
|
111
|
|
|
$this->addPatchToConfigFile( |
|
112
|
|
|
$targetPath, |
|
113
|
|
|
$this->config['paths']['patchFilesDir'] . '/' . $this->now->getTimestamp() . '.txt' |
|
114
|
|
|
); |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
private function managePath($path, $type) |
|
118
|
|
|
{ |
|
119
|
|
|
if (substr($path, 0, 1) !== '/' && !filter_var($path, FILTER_VALIDATE_URL)) { |
|
120
|
|
|
$path = $this->config['paths']['rootDir'] . '/' . $path; |
|
121
|
|
|
} elseif (filter_var($path, FILTER_VALIDATE_URL)) { |
|
122
|
|
|
if (copy($path, $this->config['paths']['patchFilesDir'] . "/$type/" . $this->now->getTimestamp())) { |
|
123
|
|
|
$path = $this->config['paths']['patchFilesDir'] . "/$type/" . $this->now->getTimestamp(); |
|
124
|
|
|
} |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
return $path; |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
private function addPatchToConfigFile($targetPath, $patchFile) |
|
131
|
|
|
{ |
|
132
|
|
|
$conf = [ |
|
133
|
|
|
'patches' => [ |
|
134
|
|
|
[ |
|
135
|
|
|
'id' => $this->now->getTimestamp(), |
|
136
|
|
|
'enabled' => true, |
|
137
|
|
|
'patched' => false, |
|
138
|
|
|
'targetFile' => $targetPath, |
|
139
|
|
|
'patchFile' => str_replace($this->config['paths']['rootDir'] . '/', '', $patchFile), |
|
140
|
|
|
], |
|
141
|
|
|
], |
|
142
|
|
|
]; |
|
143
|
|
|
|
|
144
|
|
|
$fullConf = array_merge($conf['patches'], $this->config['patches']); |
|
145
|
|
|
$yamlConfig = Yaml::dump(['patches' => $fullConf]); |
|
146
|
|
|
|
|
147
|
|
|
file_put_contents($this->config['paths']['configFile'], $yamlConfig); |
|
148
|
|
|
} |
|
149
|
|
|
} |
|
150
|
|
|
|
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.