Skip to content
Snippets Groups Projects
Commit 24620958 authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3356638 by phenaproxima, Wim Leers, tedbow: Improve hook_help() to...

Issue #3356638 by phenaproxima, Wim Leers, tedbow: Improve hook_help() to explain the actual Composer requirements
parent 7e574c13
No related branches found
No related tags found
No related merge requests found
...@@ -26,7 +26,15 @@ function package_manager_help($route_name, RouteMatchInterface $route_match) { ...@@ -26,7 +26,15 @@ function package_manager_help($route_name, RouteMatchInterface $route_match) {
$output .= '<ul>'; $output .= '<ul>';
$output .= ' <li>' . t("The Drupal application's codebase must be writable in order to use Automatic Updates. This includes Drupal core, modules, themes and the Composer dependencies in the <code>vendor</code> directory. This makes Automatic Updates incompatible with some hosting platforms.") . '</li>'; $output .= ' <li>' . t("The Drupal application's codebase must be writable in order to use Automatic Updates. This includes Drupal core, modules, themes and the Composer dependencies in the <code>vendor</code> directory. This makes Automatic Updates incompatible with some hosting platforms.") . '</li>';
$output .= ' <li>' . t('Package Manager requires a Composer executable whose version satisfies <code>@version</code>, and PHP must have permission to run it. The path to the executable may be stored in config, or it will be automatically detected. To set the path to Composer, you can add the following line to settings.php:', ['@version' => ComposerInspector::SUPPORTED_VERSION]) . '</li>'; $output .= ' <li>' . t('Package Manager requires a Composer executable whose version satisfies <code>@version</code>, and PHP must have permission to run it. The path to the executable may be stored in config, or it will be automatically detected. To set the path to Composer, you can add the following line to settings.php:', ['@version' => ComposerInspector::SUPPORTED_VERSION]) . '</li>';
$output .= '</ul>'; $output .= ' <li>' . t("Your Drupal site's <code>composer.json</code> file must be valid according to <code>composer validate</code>. See <a href=\":url\">Composer's documentation</a> for more information.", [':url' => 'https://getcomposer.org/doc/03-cli.md#validate']) . '</li>';
$output .= ' <li>' . t('Composer must be configured for secure downloads. This means that <a href=":disable-tls">the <code>disable-tls</code> option</a> must be <code>false</code>, and <a href=":secure-http">the <code>secure-http</code> option</a> must be <code>true</code> in the <code>config</code> section of your <code>composer.json</code> file. If these options are not set in your <code>composer.json</code>, Composer will behave securely by default. To set these values at the command line, run the following commands:', [
':disable-tls' => 'https://getcomposer.org/doc/06-config.md#disable-tls',
':secure-http' => 'https://getcomposer.org/doc/06-config.md#secure-http',
]);
$output .= '<pre><code>';
$output .= "composer config --unset disable-tls\n";
$output .= "composer config --unset secure-http\n";
$output .= '</code></pre></li></ul>';
$output .= '<h3 id="package-manager-limitations">' . t('Limitations') . '</h3>'; $output .= '<h3 id="package-manager-limitations">' . t('Limitations') . '</h3>';
$output .= '<p>' . t("Because Package Manager modifies the current site's code base, it is intentionally limited in certain ways to prevent unexpected changes to the live site:") . '</p>'; $output .= '<p>' . t("Because Package Manager modifies the current site's code base, it is intentionally limited in certain ways to prevent unexpected changes to the live site:") . '</p>';
......
...@@ -54,14 +54,13 @@ class ComposerValidator implements EventSubscriberInterface { ...@@ -54,14 +54,13 @@ class ComposerValidator implements EventSubscriberInterface {
$this->composerInspector->validate($dir); $this->composerInspector->validate($dir);
} }
catch (\Throwable $e) { catch (\Throwable $e) {
// @todo There are other reasons this exception could have happened
// besides Composer not being found. Explain those reasons in our online
// help, and update this link, in https://drupal.org/i/3357657.
if ($this->moduleHandler->moduleExists('help')) { if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page', ['name' => 'package_manager'])
->setOption('fragment', 'package-manager-faq-composer-not-found')
->toString();
$message = $this->t('@message See <a href=":package-manager-help">the help page</a> for information on how to configure the path to Composer.', [ $message = $this->t('@message See <a href=":package-manager-help">the help page</a> for information on how to configure the path to Composer.', [
'@message' => $e->getMessage(), '@message' => $e->getMessage(),
':package-manager-help' => $url, ':package-manager-help' => self::getHelpUrl('package-manager-faq-composer-not-found'),
]); ]);
$event->addError([$message]); $event->addError([$message]);
} }
...@@ -87,15 +86,41 @@ class ComposerValidator implements EventSubscriberInterface { ...@@ -87,15 +86,41 @@ class ComposerValidator implements EventSubscriberInterface {
// If disable-tls is enabled, it overrides secure-http and sets its value to // If disable-tls is enabled, it overrides secure-http and sets its value to
// FALSE, even if secure-http is set to TRUE explicitly. // FALSE, even if secure-http is set to TRUE explicitly.
if ($settings['disable-tls'] === TRUE) { if ($settings['disable-tls'] === TRUE) {
$messages[] = $this->t('TLS must be enabled for HTTPS Composer downloads. See <a href=":url">the Composer documentation</a> for more information.', [ $message = $this->t('TLS must be enabled for HTTPS Composer downloads.');
':url' => 'https://getcomposer.org/doc/06-config.md#disable-tls',
]); // If the Help module is installed, link to our help page, which displays
// the commands for configuring Composer correctly. Otherwise, direct
// users straight to the Composer documentation, which is a little less
// helpful.
if ($this->moduleHandler->moduleExists('help')) {
$messages[] = $this->t('@message See <a href=":url">the help page</a> for more information on how to configure Composer to download packages securely.', [
'@message' => $message,
':url' => self::getHelpUrl('package-manager-requirements'),
]);
}
else {
$messages[] = $this->t('@message See <a href=":url">the Composer documentation</a> for more information.', [
'@message' => $message,
':url' => 'https://getcomposer.org/doc/06-config.md#disable-tls',
]);
}
$messages[] = $this->t('You should also check the value of <code>secure-http</code> and make sure that it is set to <code>true</code> or not set at all.'); $messages[] = $this->t('You should also check the value of <code>secure-http</code> and make sure that it is set to <code>true</code> or not set at all.');
} }
elseif ($settings['secure-http'] !== TRUE) { elseif ($settings['secure-http'] !== TRUE) {
$messages[] = $this->t('HTTPS must be enabled for Composer downloads. See <a href=":url">the Composer documentation</a> for more information.', [ $message = $this->t('HTTPS must be enabled for Composer downloads.');
':url' => 'https://getcomposer.org/doc/06-config.md#secure-http',
]); if ($this->moduleHandler->moduleExists('help')) {
$messages[] = $this->t('@message See <a href=":url">the help page</a> for more information on how to configure Composer to download packages securely.', [
'@message' => $message,
':url' => self::getHelpUrl('package-manager-requirements'),
]);
}
else {
$messages[] = $this->t('@message See <a href=":url">the Composer documentation</a> for more information.', [
'@message' => $message,
':url' => 'https://getcomposer.org/doc/06-config.md#secure-http',
]);
}
} }
if ($messages) { if ($messages) {
...@@ -103,4 +128,19 @@ class ComposerValidator implements EventSubscriberInterface { ...@@ -103,4 +128,19 @@ class ComposerValidator implements EventSubscriberInterface {
} }
} }
/**
* Returns a URL to a specific fragment of Package Manager's online help.
*
* @param string $fragment
* The fragment to link to.
*
* @return string
* A URL to Package Manager's online help.
*/
private static function getHelpUrl(string $fragment): string {
return Url::fromRoute('help.page', ['name' => 'package_manager'])
->setOption('fragment', $fragment)
->toString();
}
} }
...@@ -118,6 +118,48 @@ class ComposerValidatorTest extends PackageManagerKernelTestBase { ...@@ -118,6 +118,48 @@ class ComposerValidatorTest extends PackageManagerKernelTestBase {
$this->assertResults($expected_results, PreApplyEvent::class); $this->assertResults($expected_results, PreApplyEvent::class);
} }
/**
* Data provider for ::testLinkToOnlineHelp().
*
* @return array[]
* The test cases.
*/
public function providerLinkToOnlineHelp(): array {
return [
'TLS disabled' => [
['disable-tls' => TRUE],
[
t('TLS must be enabled for HTTPS Composer downloads. See <a href="/admin/help/package_manager#package-manager-requirements">the help page</a> for more information on how to configure Composer to download packages securely.'),
t('You should also check the value of <code>secure-http</code> and make sure that it is set to <code>true</code> or not set at all.'),
],
],
'secure-http is off' => [
['secure-http' => FALSE],
[
t('HTTPS must be enabled for Composer downloads. See <a href="/admin/help/package_manager#package-manager-requirements">the help page</a> for more information on how to configure Composer to download packages securely.'),
],
],
];
}
/**
* Tests that invalid configuration links to online help, if available.
*
* @param array $config
* The Composer configuration to set.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup[] $expected_messages
* The expected validation error messages.
*
* @dataProvider providerLinkToOnlineHelp
*/
public function testLinkToOnlineHelp(array $config, array $expected_messages): void {
$this->enableModules(['help']);
(new ActiveFixtureManipulator())->addConfig($config)->commitChanges();
$result = ValidationResult::createError($expected_messages, t("Composer settings don't satisfy Package Manager's requirements."));
$this->assertStatusCheckResults([$result]);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment