Mercurial > hg > cmmr2012-drupal-site
comparison vendor/chi-teck/drupal-code-generator/src/Command/Drupal_8/Project.php @ 5:12f9dff5fda9 tip
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:34:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:a9cd425dd02b | 5:12f9dff5fda9 |
---|---|
1 <?php | |
2 | |
3 namespace DrupalCodeGenerator\Command\Drupal_8; | |
4 | |
5 use DrupalCodeGenerator\Command\BaseGenerator; | |
6 use DrupalCodeGenerator\Utils; | |
7 use Symfony\Component\Console\Input\InputInterface; | |
8 use Symfony\Component\Console\Output\OutputInterface; | |
9 use Symfony\Component\Console\Question\ConfirmationQuestion; | |
10 use Symfony\Component\Console\Question\Question; | |
11 | |
12 /** | |
13 * Implements d8:composer command. | |
14 * | |
15 * Inspired by drupal-composer/drupal-project. | |
16 */ | |
17 class Project extends BaseGenerator { | |
18 | |
19 protected $name = 'd8:project'; | |
20 protected $description = 'Generates a composer project'; | |
21 protected $alias = 'project'; | |
22 | |
23 const DRUPAL_DEFAULT_VERSION = '~8.6.0'; | |
24 | |
25 /** | |
26 * {@inheritdoc} | |
27 */ | |
28 protected function interact(InputInterface $input, OutputInterface $output) { | |
29 | |
30 $name_validator = function ($value) { | |
31 if (!preg_match('#[^/]+/[^/]+$#i', $value)) { | |
32 throw new \UnexpectedValueException('The value is not correct project name.'); | |
33 } | |
34 return $value; | |
35 }; | |
36 $questions['name'] = new Question('Project name (vendor/name)', FALSE); | |
37 $questions['name']->setValidator($name_validator); | |
38 | |
39 $questions['description'] = new Question('Description'); | |
40 | |
41 $questions['license'] = new Question('License', 'GPL-2.0-or-later'); | |
42 // @see https://getcomposer.org/doc/04-schema.md#license | |
43 $licenses = [ | |
44 'Apache-2.0', | |
45 'BSD-2-Clause', | |
46 'BSD-3-Clause', | |
47 'BSD-4-Clause', | |
48 'GPL-2.0-only', | |
49 'GPL-2.0-or-later', | |
50 'GPL-3.0-only', | |
51 'GPL-3.0-or-later', | |
52 'LGPL-2.1-onl', | |
53 'LGPL-2.1-or-later', | |
54 'LGPL-3.0-only', | |
55 'LGPL-3.0-or-later', | |
56 'MIT', | |
57 'proprietary', | |
58 ]; | |
59 $questions['license']->setAutocompleterValues($licenses); | |
60 | |
61 // Suggest most typical document roots. | |
62 $document_roots = [ | |
63 'docroot', | |
64 'web', | |
65 'www', | |
66 'public_html', | |
67 'public', | |
68 'htdocs', | |
69 'httpdocs', | |
70 'html', | |
71 ]; | |
72 $questions['document_root'] = new Question('Document root directory, type single dot to use Composer root', 'docroot'); | |
73 $questions['document_root']->setNormalizer(function ($value) { | |
74 return $value == '.' ? '' : $value; | |
75 }); | |
76 $questions['document_root']->setAutocompleterValues($document_roots); | |
77 | |
78 $questions['php'] = new Question('PHP version', '>=' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION); | |
79 $questions['drupal'] = new Question('Drupal version', self::DRUPAL_DEFAULT_VERSION); | |
80 $questions['drupal_core_strict'] = new ConfirmationQuestion('Would you like to get the same versions of Drupal core\'s dependencies as in Drupal core\'s composer.lock file?', FALSE); | |
81 | |
82 $this->collectVars($input, $output, $questions); | |
83 | |
84 $sections = ['require', 'require-dev']; | |
85 | |
86 $questions['drush'] = new ConfirmationQuestion('Would you like to install Drush?', TRUE); | |
87 $vars = $this->collectVars($input, $output, $questions); | |
88 if ($vars['drush']) { | |
89 $questions['drush_installation'] = new Question('Drush installation (require|require-dev)', 'require'); | |
90 $questions['drush_installation']->setValidator(Utils::getOptionsValidator($sections)); | |
91 $questions['drush_installation']->setAutocompleterValues($sections); | |
92 $this->collectVars($input, $output, $questions); | |
93 } | |
94 | |
95 $questions['drupal_console'] = new ConfirmationQuestion('Would you like to install Drupal Console?', !$vars['drush']); | |
96 $vars = $this->collectVars($input, $output, $questions); | |
97 if ($vars['drupal_console']) { | |
98 $questions['drupal_console_installation'] = new Question('Drupal Console installation (require|require-dev)', 'require-dev'); | |
99 $questions['drupal_console_installation']->setValidator(Utils::getOptionsValidator($sections)); | |
100 $questions['drupal_console_installation']->setAutocompleterValues($sections); | |
101 $this->collectVars($input, $output, $questions); | |
102 } | |
103 | |
104 $questions['composer_patches'] = new ConfirmationQuestion('Would you like to install Composer patches plugin?', TRUE); | |
105 $questions['composer_merge'] = new ConfirmationQuestion('Would you like to install Composer merge plugin?', FALSE); | |
106 $questions['behat'] = new ConfirmationQuestion('Would you like to create Behat tests?', FALSE); | |
107 $questions['env'] = new ConfirmationQuestion('Would you like to load environment variables from .env files?', FALSE); | |
108 $questions['asset_packagist'] = new ConfirmationQuestion('Would you like to add asset-packagist repository?', FALSE); | |
109 | |
110 $vars = &$this->collectVars($input, $output, $questions); | |
111 | |
112 $vars['document_root_path'] = $vars['document_root'] ? | |
113 $vars['document_root'] . '/' : $vars['document_root']; | |
114 | |
115 $this->addFile('composer.json') | |
116 ->content(self::buildComposerJson($vars)); | |
117 | |
118 $this->addFile('.gitignore') | |
119 ->template('d8/_project/gitignore.twig'); | |
120 | |
121 $this->addFile('phpcs.xml') | |
122 ->template('d8/_project/phpcs.xml.twig'); | |
123 | |
124 $this->addFile('scripts/composer/create_required_files.php') | |
125 ->template('d8/_project/scripts/composer/create_required_files.php.twig'); | |
126 | |
127 if ($vars['behat']) { | |
128 $this->addFile('tests/behat/behat.yml') | |
129 ->template('d8/_project/tests/behat/behat.yml.twig'); | |
130 | |
131 $this->addFile('tests/behat/local.behat.yml') | |
132 ->template('d8/_project/tests/behat/local.behat.yml.twig'); | |
133 | |
134 $this->addFile('tests/behat/bootstrap/BaseContext.php') | |
135 ->template('d8/_project/tests/behat/bootstrap/BaseContext.php.twig'); | |
136 | |
137 $this->addFile('tests/behat/bootstrap/ExampleContext.php') | |
138 ->template('d8/_project/tests/behat/bootstrap/ExampleContext.php.twig'); | |
139 | |
140 $this->addFile('tests/behat/features/example/user_forms.feature') | |
141 ->template('d8/_project/tests/behat/features/example/user_forms.feature.twig'); | |
142 } | |
143 | |
144 if ($vars['env']) { | |
145 $this->addFile('.env.example') | |
146 ->template('d8/_project/env.example.twig'); | |
147 $this->addFile('load.environment.php') | |
148 ->template('d8/_project/load.environment.php.twig'); | |
149 } | |
150 | |
151 if ($vars['document_root']) { | |
152 $this->addDirectory('config/sync'); | |
153 } | |
154 | |
155 if ($vars['drush']) { | |
156 $this->addFile('drush/drush.yml') | |
157 ->template('d8/_project/drush/drush.yml.twig'); | |
158 $this->addFile('drush/Commands/PolicyCommands.php') | |
159 ->template('d8/_project/drush/Commands/PolicyCommands.php.twig'); | |
160 $this->addFile('drush/sites/self.site.yml') | |
161 ->template('d8/_project/drush/sites/self.site.yml.twig'); | |
162 $this->addFile('scripts/sync-site.sh') | |
163 ->template('d8/_project/scripts/sync-site.sh.twig') | |
164 ->mode(0544); | |
165 } | |
166 | |
167 $this->addFile('patches/.keep')->content(''); | |
168 $this->addDirectory($vars['document_root_path'] . 'modules/contrib'); | |
169 $this->addDirectory($vars['document_root_path'] . 'modules/custom'); | |
170 $this->addDirectory($vars['document_root_path'] . 'modules/custom'); | |
171 $this->addDirectory($vars['document_root_path'] . 'libraries'); | |
172 } | |
173 | |
174 /** | |
175 * {@inheritdoc} | |
176 */ | |
177 protected function execute(InputInterface $input, OutputInterface $output) { | |
178 $result = parent::execute($input, $output); | |
179 if ($result === 0) { | |
180 $output->writeln(' <info>Next steps:</info>'); | |
181 $output->writeln(' <info>–––––––––––</info>'); | |
182 $output->writeln(' <info>1. Review generated files</info>'); | |
183 $output->writeln(' <info>2. Run <comment>composer install</comment> command</info>'); | |
184 $output->writeln(' <info>3. Install Drupal</info>'); | |
185 $output->writeln(''); | |
186 } | |
187 return $result; | |
188 } | |
189 | |
190 /** | |
191 * Builds composer.json file. | |
192 * | |
193 * @param array $vars | |
194 * Collected variables. | |
195 * | |
196 * @return string | |
197 * Encoded JSON content. | |
198 */ | |
199 protected static function buildComposerJson(array $vars) { | |
200 | |
201 $document_root_path = $vars['document_root_path']; | |
202 | |
203 $composer_json = []; | |
204 | |
205 $composer_json['name'] = $vars['name']; | |
206 $composer_json['description'] = $vars['description']; | |
207 $composer_json['type'] = 'project'; | |
208 $composer_json['license'] = $vars['license']; | |
209 | |
210 $composer_json['repositories'][] = [ | |
211 'type' => 'composer', | |
212 'url' => 'https://packages.drupal.org/8', | |
213 ]; | |
214 if ($vars['asset_packagist']) { | |
215 $composer_json['repositories'][] = [ | |
216 'type' => 'composer', | |
217 'url' => 'https://asset-packagist.org', | |
218 ]; | |
219 } | |
220 | |
221 $require = []; | |
222 $require_dev = []; | |
223 | |
224 self::addPackage($require, 'drupal/core'); | |
225 $require['drupal/core'] = $vars['drupal']; | |
226 self::addPackage($require, 'composer/installers'); | |
227 self::addPackage($require, 'drupal-composer/drupal-scaffold'); | |
228 self::addPackage($require, 'zaporylie/composer-drupal-optimizations'); | |
229 $require_dev['webflo/drupal-core-require-dev'] = $vars['drupal']; | |
230 | |
231 if ($vars['asset_packagist']) { | |
232 self::addPackage($require, 'oomphinc/composer-installers-extender'); | |
233 } | |
234 | |
235 if ($vars['drupal_core_strict']) { | |
236 $require['webflo/drupal-core-strict'] = $vars['drupal']; | |
237 } | |
238 | |
239 if ($vars['drush']) { | |
240 $vars['drush_installation'] == 'require' | |
241 ? self::addPackage($require, 'drush/drush') | |
242 : self::addPackage($require_dev, 'drush/drush'); | |
243 } | |
244 | |
245 if ($vars['drupal_console']) { | |
246 $vars['drupal_console_installation'] == 'require' | |
247 ? self::addPackage($require, 'drupal/console') | |
248 : self::addPackage($require_dev, 'drupal/console'); | |
249 } | |
250 | |
251 if ($vars['composer_patches']) { | |
252 self::addPackage($require, 'cweagans/composer-patches'); | |
253 } | |
254 | |
255 if ($vars['composer_merge']) { | |
256 self::addPackage($require, 'wikimedia/composer-merge-plugin'); | |
257 } | |
258 | |
259 if ($vars['behat']) { | |
260 // Behat and Mink drivers are Drupal core dev dependencies. | |
261 self::addPackage($require_dev, 'drupal/drupal-extension'); | |
262 } | |
263 | |
264 if ($vars['env']) { | |
265 self::addPackage($require, 'symfony/dotenv'); | |
266 } | |
267 | |
268 $composer_json['require'] = [ | |
269 'php' => $vars['php'], | |
270 'ext-curl' => '*', | |
271 'ext-gd' => '*', | |
272 'ext-json' => '*', | |
273 ]; | |
274 ksort($require); | |
275 $composer_json['require'] += $require; | |
276 | |
277 ksort($require_dev); | |
278 $composer_json['require-dev'] = $require_dev; | |
279 | |
280 // PHPUnit is core dev dependency. | |
281 $composer_json['scripts']['phpunit'] = 'phpunit --colors=always --configuration ' . $document_root_path . 'core ' . $document_root_path . 'modules/custom'; | |
282 if ($vars['behat']) { | |
283 $composer_json['scripts']['behat'] = 'behat --colors --config=tests/behat/local.behat.yml'; | |
284 } | |
285 $composer_json['scripts']['phpcs'] = 'phpcs --standard=phpcs.xml'; | |
286 $composer_json['scripts']['post-install-cmd'][] = '@php ./scripts/composer/create_required_files.php'; | |
287 $composer_json['scripts']['post-update-cmd'][] = '@php ./scripts/composer/create_required_files.php'; | |
288 | |
289 $composer_json['minimum-stability'] = 'dev'; | |
290 $composer_json['prefer-stable'] = TRUE; | |
291 | |
292 $composer_json['config'] = [ | |
293 'sort-packages' => TRUE, | |
294 'bin-dir' => 'bin', | |
295 ]; | |
296 | |
297 if ($vars['env']) { | |
298 $composer_json['autoload']['files'][] = 'load.environment.php'; | |
299 } | |
300 | |
301 if ($vars['composer_patches']) { | |
302 $composer_json['extra']['composer-exit-on-patch-failure'] = TRUE; | |
303 } | |
304 | |
305 if ($vars['asset_packagist']) { | |
306 $composer_json['extra']['installer-types'] = [ | |
307 'bower-asset', | |
308 'npm-asset', | |
309 ]; | |
310 } | |
311 $composer_json['extra']['installer-paths'] = [ | |
312 $document_root_path . 'core' => ['type:drupal-core'], | |
313 $document_root_path . 'libraries/{$name}' => ['type:drupal-library'], | |
314 $document_root_path . 'modules/contrib/{$name}' => ['type:drupal-module'], | |
315 $document_root_path . 'themes/{$name}' => ['type:drupal-theme'], | |
316 'drush/{$name}' => ['type:drupal-drush'], | |
317 ]; | |
318 if ($vars['asset_packagist']) { | |
319 $composer_json['extra']['installer-paths'][$document_root_path . 'libraries/{$name}'][] = 'type:bower-asset'; | |
320 $composer_json['extra']['installer-paths'][$document_root_path . 'libraries/{$name}'][] = 'type:npm-asset'; | |
321 } | |
322 | |
323 $composer_json['extra']['drupal-scaffold']['excludes'] = [ | |
324 '.csslintrc', | |
325 '.editorconfig', | |
326 '.eslintignore', | |
327 '.eslintrc.json', | |
328 '.gitattributes', | |
329 '.ht.router.php', | |
330 '.htaccess', | |
331 'robots.txt', | |
332 'update.php', | |
333 'web.config', | |
334 ]; | |
335 // Initial files are created but never updated. | |
336 $composer_json['extra']['drupal-scaffold']['initial'] = [ | |
337 '.htaccess' => '.htaccess', | |
338 'robots.txt' => 'robots.txt', | |
339 ]; | |
340 | |
341 // Move these files to Composer root. | |
342 if ($vars['document_root']) { | |
343 $composer_json['extra']['drupal-scaffold']['initial']['.editorconfig'] = '../.editorconfig'; | |
344 $composer_json['extra']['drupal-scaffold']['initial']['.gitattributes'] = '../.gitattributes'; | |
345 } | |
346 ksort($composer_json['extra']['drupal-scaffold']['initial']); | |
347 | |
348 if ($vars['composer_merge']) { | |
349 $composer_json['extra']['merge-plugin'] = [ | |
350 'include' => [ | |
351 $document_root_path . 'modules/custom/*/composer.json', | |
352 ], | |
353 'recurse' => TRUE, | |
354 ]; | |
355 } | |
356 | |
357 return json_encode($composer_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"; | |
358 } | |
359 | |
360 /** | |
361 * Requires a given package. | |
362 * | |
363 * @param array $section | |
364 * Section for the package (require|require-dev) | |
365 * @param string $package | |
366 * A package to be added. | |
367 * | |
368 * @todo Find a way to track versions automatically. | |
369 */ | |
370 protected static function addPackage(array &$section, $package) { | |
371 $versions = [ | |
372 'composer/installers' => '^1.4', | |
373 'cweagans/composer-patches' => '^1.6', | |
374 'drupal-composer/drupal-scaffold' => '^2.5', | |
375 'drupal/console' => '^1.0', | |
376 'drupal/core' => self::DRUPAL_DEFAULT_VERSION, | |
377 'drupal/drupal-extension' => '^3.4', | |
378 'drush/drush' => '^9.6', | |
379 'oomphinc/composer-installers-extender' => '^1.1', | |
380 'symfony/dotenv' => '^3.4', | |
381 'webflo/drupal-core-require-dev' => self::DRUPAL_DEFAULT_VERSION, | |
382 'webflo/drupal-core-strict' => self::DRUPAL_DEFAULT_VERSION, | |
383 'wikimedia/composer-merge-plugin' => '^1.4', | |
384 'zaporylie/composer-drupal-optimizations' => '^1.1', | |
385 ]; | |
386 $section[$package] = $versions[$package]; | |
387 } | |
388 | |
389 } |