function LockFileValidator::validate

Checks that the active lock file is unchanged during stage operations.

Parameters

\Drupal\package_manager\Event\PreOperationStageEvent $event: The event being handled.

File

core/modules/package_manager/src/Validator/LockFileValidator.php, line 111

Class

LockFileValidator
Checks that the active lock file is unchanged during stage operations.

Namespace

Drupal\package_manager\Validator

Code

public function validate(PreOperationStageEvent $event) : void {
    $stage = $event->stage;
    // Early return if the stage is not already created.
    if ($event instanceof StatusCheckEvent && $stage->isAvailable()) {
        return;
    }
    $messages = [];
    // Ensure we can get a current hash of the lock file.
    $active_lock_file_path = $this->pathLocator
        ->getProjectRoot() . DIRECTORY_SEPARATOR . 'composer.lock';
    $active_lock_file_hash = $this->getHash($active_lock_file_path);
    if (empty($active_lock_file_hash)) {
        $messages[] = $this->t('The active lock file (@file) does not exist.', [
            '@file' => $active_lock_file_path,
        ]);
    }
    // Ensure we also have a stored hash of the lock file.
    $active_lock_file_stored_hash = $this->keyValue
        ->get(static::KEY);
    if (empty($active_lock_file_stored_hash)) {
        throw new \LogicException('Stored hash key deleted.');
    }
    // If we have both hashes, ensure they match.
    if ($active_lock_file_hash && !hash_equals($active_lock_file_stored_hash, $active_lock_file_hash)) {
        $messages[] = $this->t('Unexpected changes were detected in the active lock file (@file), which indicates that other Composer operations were performed since this Package Manager operation started. This can put the code base into an unreliable state and therefore is not allowed.', [
            '@file' => $active_lock_file_path,
        ]);
    }
    // Don't allow staged changes to be applied if the staged lock file has no
    // apparent changes.
    if (empty($messages) && $event instanceof PreApplyEvent) {
        $staged_lock_file_path = $stage->getStageDirectory() . DIRECTORY_SEPARATOR . 'composer.lock';
        $staged_lock_file_hash = $this->getHash($staged_lock_file_path);
        if ($staged_lock_file_hash && hash_equals($active_lock_file_hash, $staged_lock_file_hash)) {
            $messages[] = $this->t('There appear to be no pending Composer operations because the active lock file (@active_file) and the staged lock file (@staged_file) are identical.', [
                '@active_file' => $active_lock_file_path,
                '@staged_file' => $staged_lock_file_path,
            ]);
        }
    }
    if (!empty($messages)) {
        $summary = $this->formatPlural(count($messages), 'Problem detected in lock file during stage operations.', 'Problems detected in lock file during stage operations.');
        $event->addError($messages, $summary);
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.