Skip to content
Snippets Groups Projects
Commit 15b871ae authored by Kunal Sachdev's avatar Kunal Sachdev Committed by Adam G-H
Browse files

Issue #3253858 by kunal.sachdev, phenaproxima, tedbow: In...

Issue #3253858 by kunal.sachdev, phenaproxima, tedbow: In ComposerExecutableValidator provide in explanation about how you can set the path to the Composer executable
parent bf9874f6
No related branches found
Tags 11-40901
No related merge requests found
......@@ -17,7 +17,7 @@ function package_manager_help($route_name, RouteMatchInterface $route_match) {
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Package Manager is a framework for updating Drupal core and installing contributed modules and themes via Composer. It has no user interface, but it provides an API for creating a temporary copy of the current site, making changes to the copy, and then syncing those changes back into the live site.') . '</p>';
$output .= '<p>' . t('Package Manager dispatches events before and after various operations, and external code can integrate with it by subscribing to those events. For more information, see <code>package_manager.api.php</code>.') . '</p>';
$output .= '<h3>' . t('Requirements') . '</h3>';
$output .= '<h3 id="package-manager-requirements">' . t('Requirements') . '</h3>';
$output .= '<p>' . t('Package Manager requires Composer @version or later available as an executable, and PHP must have permission to run it. The path to the executable may be set in the <code>package_manager.settings:executables.composer</code> config setting, or it will be automatically detected.', ['@version' => ComposerExecutableValidator::MINIMUM_COMPOSER_VERSION]) . '</p>';
$output .= '<h3>' . 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 from being made to the live site:") . '</p>';
......
......@@ -80,6 +80,7 @@ services:
class: Drupal\package_manager\Validator\ComposerExecutableValidator
arguments:
- '@package_manager.composer_runner'
- '@module_handler'
- '@string_translation'
tags:
- { name: event_subscriber }
......
......@@ -3,6 +3,8 @@
namespace Drupal\package_manager\Validator;
use Composer\Semver\Comparator;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Url;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Event\PreOperationStageEvent;
use Drupal\Core\StringTranslation\StringTranslationTrait;
......@@ -32,6 +34,13 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface
*/
protected $composer;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The detected version of Composer.
*
......@@ -44,11 +53,14 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface
*
* @param \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface $composer
* The Composer runner.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* The translation service.
*/
public function __construct(ComposerRunnerInterface $composer, TranslationInterface $translation) {
public function __construct(ComposerRunnerInterface $composer, ModuleHandlerInterface $module_handler, TranslationInterface $translation) {
$this->composer = $composer;
$this->moduleHandler = $module_handler;
$this->setStringTranslation($translation);
}
......@@ -60,27 +72,47 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface
$this->composer->run(['--version'], $this);
}
catch (ExceptionInterface $e) {
$event->addError([
$e->getMessage(),
]);
$this->setError($e->getMessage(), $event);
return;
}
if ($this->version) {
if (Comparator::lessThan($this->version, static::MINIMUM_COMPOSER_VERSION)) {
$event->addError([
$this->t('Composer @minimum_version or later is required, but version @detected_version was detected.', [
'@minimum_version' => static::MINIMUM_COMPOSER_VERSION,
'@detected_version' => $this->version,
]),
$message = $this->t('Composer @minimum_version or later is required, but version @detected_version was detected.', [
'@minimum_version' => static::MINIMUM_COMPOSER_VERSION,
'@detected_version' => $this->version,
]);
$this->setError($message, $event);
}
}
else {
$event->addError([
$this->t('The Composer version could not be detected.'),
$this->setError($this->t('The Composer version could not be detected.'), $event);
}
}
/**
* Flags a validation error.
*
* @param string $message
* The error message. If the Help module is enabled, a link to Package
* Manager's online documentation will be appended.
* @param \Drupal\package_manager\Event\PreOperationStageEvent $event
* The event object.
*
* @see package_manager_help()
*/
protected function setError(string $message, PreOperationStageEvent $event): void {
if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page', ['name' => 'package_manager'])
->setOption('fragment', 'package-manager-requirements')
->toString();
$message .= ' ';
$message .= $this->t('See <a href=":package-manager-help">the help page</a> for information on how to configure the path to Composer.', [
':package-manager-help' => $url,
]);
}
$event->addError([$message]);
}
/**
......
......@@ -2,6 +2,7 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\Url;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Validator\ComposerExecutableValidator;
use Drupal\package_manager\ValidationResult;
......@@ -35,6 +36,10 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
$exception->getMessage(),
]);
$this->assertResults([$error], PreCreateEvent::class);
$this->enableModules(['help']);
$this->container->set('package_manager.executable_finder', $exec_finder->reveal());
$this->assertResultsWithHelp([$error], PreCreateEvent::class);
}
/**
......@@ -137,6 +142,36 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// If the validator can't find a recognized, supported version of Composer,
// it should produce errors.
$this->assertResults($expected_results, PreCreateEvent::class);
$this->enableModules(['help']);
$this->container->set('package_manager.composer_runner', $runner->reveal());
$this->assertResultsWithHelp($expected_results, PreCreateEvent::class);
}
/**
* Asserts that a set of validation results link to the Package Manager help.
*
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results.
* @param string|null $event_class
* (optional) The class of the event which should return the results. Must
* be passed if $expected_results is not empty.
*/
private function assertResultsWithHelp(array $expected_results, string $event_class = NULL): void {
$url = Url::fromRoute('help.page', ['name' => 'package_manager'])
->setOption('fragment', 'package-manager-requirements')
->toString();
// Reformat the provided results so that they all have the link to the
// online documentation appended to them.
$map = function (string $message) use ($url): string {
return $message . ' See <a href="' . $url . '">the help page</a> for information on how to configure the path to Composer.';
};
foreach ($expected_results as $index => $result) {
$messages = array_map($map, $result->getMessages());
$expected_results[$index] = ValidationResult::createError($messages);
}
$this->assertResults($expected_results, $event_class);
}
}
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