|
1
|
|
|
#!/usr/bin/env php |
|
|
|
|
|
|
2
|
|
|
<?php |
|
3
|
|
|
|
|
4
|
|
|
use Symfony\Component\Console\Application; |
|
5
|
|
|
use Symfony\Component\Console\Command\Command; |
|
6
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
|
7
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
|
8
|
|
|
use Symfony\Component\Console\Input\InputOption; |
|
9
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
|
10
|
|
|
use Symfony\Component\Console\Helper\ProgressBar; |
|
11
|
|
|
use Symfony\Component\Finder\Finder; |
|
12
|
|
|
use Symfony\Component\Finder\SplFileInfo; |
|
|
|
|
|
|
13
|
|
|
use Symfony\Component\Filesystem\Filesystem; |
|
14
|
|
|
|
|
15
|
|
|
require 'src/vendor/autoload.php'; |
|
16
|
|
|
|
|
17
|
|
|
class GenerateVendorDocCommand extends Command |
|
|
|
|
|
|
18
|
|
|
{ |
|
19
|
|
|
protected function configure() |
|
20
|
|
|
{ |
|
21
|
|
|
$this |
|
22
|
|
|
->setName('build:generate_vendor_doc') |
|
23
|
|
|
->setDescription('Generates a file containing all the vendors and the installed version.') |
|
24
|
|
|
->addOption('write-to', null, InputOption::VALUE_REQUIRED, 'Where to dump the generated file.'); |
|
25
|
|
|
} |
|
26
|
|
|
|
|
27
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
28
|
|
|
{ |
|
29
|
|
|
$output->writeln('Reading composer vendors.'); |
|
30
|
|
|
$packages = json_decode(file_get_contents('composer.lock'), true); |
|
31
|
|
|
$packages = $packages['packages']; |
|
32
|
|
|
|
|
33
|
|
|
$output->writeln('Generating output'); |
|
34
|
|
|
|
|
35
|
|
|
$typeOrder = [ |
|
36
|
|
|
'zikula-module' => 'Zikula Modules', |
|
37
|
|
|
'zikula-theme' => 'Zikula Themes', |
|
38
|
|
|
'symfony-bundle' => 'Symfony Bundles', |
|
39
|
|
|
'component' => 'Web Components', |
|
40
|
|
|
'library' => 'Other PHP libraries', |
|
41
|
|
|
'composer-installer' => 'Composer Installers', |
|
42
|
|
|
'composer-plugin' => 'Composer Plugins' |
|
43
|
|
|
]; |
|
44
|
|
|
$types = array_keys($typeOrder); |
|
45
|
|
|
usort($packages, function ($a, $b) use ($types) { |
|
46
|
|
|
return array_search($a['type'], $types) - array_search($b['type'], $types); |
|
47
|
|
|
}); |
|
48
|
|
|
|
|
49
|
|
|
$content = ''; |
|
50
|
|
|
$currentType = ''; |
|
51
|
|
|
$authors = []; |
|
52
|
|
|
foreach ($packages as $package) { |
|
53
|
|
|
if ($currentType != $package['type']) { |
|
54
|
|
|
if ($currentType != '') { |
|
55
|
|
|
$content .= "\n"; |
|
56
|
|
|
} |
|
57
|
|
|
$content .= $typeOrder[$package['type']] . "\n"; |
|
58
|
|
|
$content .= str_repeat('-', strlen($typeOrder[$package['type']])) . "\n"; |
|
59
|
|
|
$currentType = $package['type']; |
|
60
|
|
|
} |
|
61
|
|
|
$content .= "- **" . $package['name'] . "** `" . $package['version'] . "`"; |
|
62
|
|
|
if (isset($package['license'])) { |
|
63
|
|
|
$content .= ", License: `" . implode(', ', $package['license']) . "`\n"; |
|
64
|
|
|
} else { |
|
65
|
|
|
$content .= "\n"; |
|
66
|
|
|
} |
|
67
|
|
|
if (isset($package['description'])) { |
|
68
|
|
|
$content .= " *" . $package['description'] . "*\n"; |
|
69
|
|
|
} |
|
70
|
|
|
if (isset($package['authors'])) { |
|
71
|
|
|
$authors = array_merge($authors, $package['authors']); |
|
72
|
|
|
} |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
$content .= "\n\n"; |
|
76
|
|
|
$content .= "These are the main authors of all of the projects supporting Zikula\n"; |
|
77
|
|
|
$content .= "-------------------------------------------------------------------\n"; |
|
78
|
|
|
|
|
79
|
|
|
$tmp = []; |
|
80
|
|
|
foreach ($authors as $k => $author) { |
|
81
|
|
|
if (in_array($author['name'], $tmp)) { |
|
82
|
|
|
unset($authors[$k]); |
|
83
|
|
|
continue; |
|
84
|
|
|
} |
|
85
|
|
|
$tmp[] = $author['name']; |
|
86
|
|
|
} |
|
87
|
|
|
foreach ($authors as $author) { |
|
88
|
|
|
$content .= "- **" . $author['name'] . "**"; |
|
89
|
|
|
if (isset($author['homepage'])) { |
|
90
|
|
|
$content .= " " . $author['homepage']; |
|
91
|
|
|
} |
|
92
|
|
|
if (isset($author['email'])) { |
|
93
|
|
|
$content .= " *" . $author['email'] . "*"; |
|
94
|
|
|
} |
|
95
|
|
|
$content .= "\n"; |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
$output->writeln('Dumping vendors to ' . $input->getOption('write-to')); |
|
99
|
|
|
|
|
100
|
|
|
file_put_contents($input->getOption('write-to'), $content); |
|
101
|
|
|
} |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
class PurgeVendorsCommand extends Command |
|
|
|
|
|
|
105
|
|
|
{ |
|
106
|
|
|
protected function configure() |
|
107
|
|
|
{ |
|
108
|
|
|
$this |
|
109
|
|
|
->setName('build:purge_vendors') |
|
110
|
|
|
->setDescription('Purges tests from vendors') |
|
111
|
|
|
->addUsage('my/package/path/vendor') |
|
112
|
|
|
->addArgument('vendor-dir', InputArgument::REQUIRED, 'Vendors dir, e.g. src/vendor'); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
116
|
|
|
{ |
|
117
|
|
|
$dir = $input->getArgument('vendor-dir'); |
|
118
|
|
|
$progress = new ProgressBar($output, 4); |
|
119
|
|
|
$progress->start(); |
|
120
|
|
|
|
|
121
|
|
|
self::cleanVendors($dir, $progress); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
public static function cleanVendors($dir, ProgressBar $progress) |
|
125
|
|
|
{ |
|
126
|
|
|
$filesystem = new Filesystem(); |
|
127
|
|
|
|
|
128
|
|
|
$finder = new Finder(); |
|
129
|
|
|
$finder->in($dir) |
|
130
|
|
|
->directories() |
|
131
|
|
|
->path('.git') |
|
132
|
|
|
->path('tests') |
|
133
|
|
|
->path('Tests') |
|
134
|
|
|
->ignoreDotFiles(false) |
|
135
|
|
|
->ignoreVCS(false); |
|
136
|
|
|
$progress->advance(); |
|
137
|
|
|
|
|
138
|
|
|
$paths = []; |
|
139
|
|
|
/** @var SplFileInfo $file */ |
|
140
|
|
|
foreach ($finder as $file) { |
|
141
|
|
|
$paths[] = $file->getRealPath(); |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
$paths = array_unique($paths); |
|
145
|
|
|
rsort($paths); |
|
146
|
|
|
|
|
147
|
|
|
$progress->advance(); |
|
148
|
|
|
$filesystem->chmod($paths, 0777, 0000, true); |
|
149
|
|
|
$progress->advance(); |
|
150
|
|
|
$filesystem->remove($paths); |
|
151
|
|
|
$progress->advance(); |
|
152
|
|
|
} |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
class FixAutoloaderCommand extends Command |
|
|
|
|
|
|
156
|
|
|
{ |
|
157
|
|
|
protected function configure() |
|
158
|
|
|
{ |
|
159
|
|
|
$this |
|
160
|
|
|
->setName('build:fix_autoloader') |
|
161
|
|
|
->setDescription('Fixes autoloader paths') |
|
162
|
|
|
->addUsage('my/package/path/vendor') |
|
163
|
|
|
->addArgument('vendor-dir', InputArgument::REQUIRED, 'Vendors dir, e.g. src/vendor'); |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
167
|
|
|
{ |
|
168
|
|
|
$dir = $input->getArgument('vendor-dir'); |
|
169
|
|
|
$progress = new ProgressBar($output, 3); |
|
170
|
|
|
$progress->start(); |
|
171
|
|
|
|
|
172
|
|
|
self::fix($dir, $progress); |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
public static function fix($dir, ProgressBar $progress) |
|
176
|
|
|
{ |
|
177
|
|
|
// fix paths in composer autoloader files removing src/ from paths |
|
178
|
|
|
$composerFiles = [ |
|
179
|
|
|
'autoload_classmap.php', |
|
180
|
|
|
'autoload_namespaces.php', |
|
181
|
|
|
'autoload_real.php', |
|
182
|
|
|
'autoload_files.php', |
|
183
|
|
|
'autoload_psr4.php', |
|
184
|
|
|
'autoload_static.php' |
|
185
|
|
|
]; |
|
186
|
|
|
foreach ($composerFiles as $file) { |
|
187
|
|
|
$file = "$dir/composer/$file"; |
|
188
|
|
|
$content = file_get_contents($file); |
|
189
|
|
|
$content = str_replace("baseDir . '/src/", "baseDir . '/", $content); |
|
190
|
|
|
$content = str_replace('dirname(dirname($vendorDir))', 'dirname($vendorDir)', $content); |
|
191
|
|
|
$content = str_replace("__DIR__ . '/../../..' . '/src", "__DIR__ . '/../..' . '", $content); |
|
192
|
|
|
file_put_contents($file, $content); |
|
193
|
|
|
$progress->advance(); |
|
194
|
|
|
} |
|
195
|
|
|
} |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
/** |
|
199
|
|
|
* UNUSED COMMAND |
|
200
|
|
|
* Class BuildPackageCommand |
|
201
|
|
|
*/ |
|
202
|
|
|
class BuildPackageCommand extends Command |
|
|
|
|
|
|
203
|
|
|
{ |
|
204
|
|
|
protected function configure() |
|
205
|
|
|
{ |
|
206
|
|
|
$this |
|
207
|
|
|
->setName('build:package') |
|
208
|
|
|
->setDescription('Packages Zikula') |
|
209
|
|
|
->addUsage('my-buildname path/to/my/build/dir path/to/my/source/dir') |
|
210
|
|
|
->addArgument('name', InputArgument::REQUIRED, 'Build name') |
|
211
|
|
|
->addArgument('source-dir', InputArgument::REQUIRED, 'Build dir') |
|
212
|
|
|
->addArgument('build-dir', InputArgument::REQUIRED, 'Source dir'); |
|
213
|
|
|
} |
|
214
|
|
|
|
|
215
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
216
|
|
|
{ |
|
217
|
|
|
$name = $input->getArgument('name'); |
|
218
|
|
|
$sourceDir = $input->getArgument('source-dir'); |
|
219
|
|
|
$buildDir = $input->getArgument('build-dir'); |
|
220
|
|
|
|
|
221
|
|
|
$progress = new ProgressBar($output, 17); |
|
222
|
|
|
$progress->start(); |
|
223
|
|
|
|
|
224
|
|
|
$filesystem = new Filesystem(); |
|
225
|
|
|
|
|
226
|
|
|
$pwd = getcwd(); |
|
227
|
|
|
if (is_dir($buildDir)) { |
|
228
|
|
|
system("rm -rf $buildDir"); |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
// build env |
|
232
|
|
|
$filesystem->mkdir($buildDir, 0755); |
|
233
|
|
|
$progress->advance(); |
|
234
|
|
|
|
|
235
|
|
|
$filesystem->mirror($sourceDir, "$buildDir/$name"); |
|
236
|
|
|
$progress->advance(); |
|
237
|
|
|
|
|
238
|
|
|
PurgeVendorsCommand::cleanVendors("$buildDir/$name/vendor", $progress); |
|
239
|
|
|
FixAutoloaderCommand::fix("$buildDir/$name/vendor", $progress); |
|
240
|
|
|
|
|
241
|
|
|
$writableArray = [ |
|
242
|
|
|
"$buildDir/$name/var/cache", |
|
243
|
|
|
"$buildDir/$name/var/logs", |
|
244
|
|
|
"$buildDir/$name/web/uploads", |
|
245
|
|
|
]; |
|
246
|
|
|
$filesystem->chmod($writableArray, 0777); |
|
247
|
|
|
$progress->advance(); |
|
248
|
|
|
|
|
249
|
|
|
chdir($buildDir); |
|
250
|
|
|
$finder = new Finder(); |
|
251
|
|
|
$finder |
|
252
|
|
|
->in($name) |
|
253
|
|
|
->files() |
|
254
|
|
|
->ignoreDotFiles(false); |
|
255
|
|
|
|
|
256
|
|
|
$allFiles = []; |
|
257
|
|
|
/** @var SplFileInfo $file */ |
|
258
|
|
|
foreach ($finder as $file) { |
|
259
|
|
|
$allFiles[] = $file->getRelativePathname(); |
|
260
|
|
|
} |
|
261
|
|
|
$progress->advance(); |
|
262
|
|
|
|
|
263
|
|
|
// build zip |
|
264
|
|
|
$zip = new \ZipArchive(); |
|
265
|
|
|
$fileName = "$name.zip"; |
|
266
|
|
|
if ($zip->open($fileName, \ZipArchive::CREATE) !== true) { |
|
267
|
|
|
$output->writeln("<error>Error creating $fileName</error>"); |
|
268
|
|
|
} |
|
269
|
|
|
|
|
270
|
|
|
foreach ($allFiles as $file) { |
|
271
|
|
|
$zip->addFile("$name/$file"); |
|
272
|
|
|
} |
|
273
|
|
|
$progress->advance(); |
|
274
|
|
|
|
|
275
|
|
|
$zip->close(); |
|
276
|
|
|
$progress->advance(); |
|
277
|
|
|
|
|
278
|
|
|
// build tar |
|
279
|
|
|
$fileName = "$name.tar"; |
|
280
|
|
|
system("tar cp $name > $fileName"); |
|
281
|
|
|
$progress->advance(); |
|
282
|
|
|
system("gzip $fileName"); |
|
283
|
|
|
$progress->advance(); |
|
284
|
|
|
|
|
285
|
|
|
// checksums |
|
286
|
|
|
$zipMd5 = md5_file("$name.zip"); |
|
287
|
|
|
$tarMd5 = md5_file("$name.tar.gz"); |
|
288
|
|
|
$zipSha1 = sha1_file("$name.zip"); |
|
289
|
|
|
$tarSha1 = sha1_file("$name.tar.gz"); |
|
290
|
|
|
|
|
291
|
|
|
$checksum = <<<CHECKSUM |
|
292
|
|
|
-----------------md5sums----------------- |
|
293
|
|
|
$zipMd5 $name.zip |
|
294
|
|
|
$tarMd5 $name.tar.gz |
|
295
|
|
|
-----------------sha1sums----------------- |
|
296
|
|
|
$zipSha1 $name.zip |
|
297
|
|
|
$tarSha1 $name.tar.gz |
|
298
|
|
|
CHECKSUM; |
|
299
|
|
|
file_put_contents("$name-checksum.txt", $checksum); |
|
300
|
|
|
$progress->advance(); |
|
301
|
|
|
|
|
302
|
|
|
// cleanup |
|
303
|
|
|
system("rm -rf $buildDir $name"); |
|
304
|
|
|
chdir($pwd); |
|
305
|
|
|
$progress->advance(); |
|
306
|
|
|
$progress->finish(); |
|
307
|
|
|
|
|
308
|
|
|
$output->writeln("<info>Artifacts built in $buildDir/ folder</info>"); |
|
309
|
|
|
} |
|
310
|
|
|
} |
|
311
|
|
|
|
|
312
|
|
|
class LessCommand extends Command |
|
|
|
|
|
|
313
|
|
|
{ |
|
314
|
|
|
protected function configure() |
|
315
|
|
|
{ |
|
316
|
|
|
$this |
|
317
|
|
|
->setName('build:generate_less') |
|
318
|
|
|
->setDescription('Generates Bootstrap Less file') |
|
319
|
|
|
->addOption('write-to', null, InputOption::VALUE_REQUIRED, 'Where to dump the generated file.'); |
|
320
|
|
|
} |
|
321
|
|
|
|
|
322
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
|
323
|
|
|
{ |
|
324
|
|
|
\Zikula\Composer\LessGenerator::generateCombinedBootstrapFontAwesomeCSS($input->getOption('write-to')); |
|
325
|
|
|
} |
|
326
|
|
|
} |
|
327
|
|
|
|
|
328
|
|
|
$application = new Application(); |
|
329
|
|
|
$application->add(new BuildPackageCommand()); |
|
330
|
|
|
$application->add(new PurgeVendorsCommand()); |
|
331
|
|
|
$application->add(new FixAutoloaderCommand()); |
|
332
|
|
|
$application->add(new GenerateVendorDocCommand()); |
|
333
|
|
|
$application->add(new LessCommand()); |
|
334
|
|
|
$application->run(); |
|
335
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.