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
No related tags found
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