Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 54 additions & 16 deletions src/Commands/core/UpdateDBCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ public function updatedb($options = ['cache-clear' => true]): int
'module' => 'Module',
'update_id' => 'Update ID',
'description' => 'Description',
'type' => 'Type'
'type' => 'Type',
'allowed' => 'Allowed',
])]
#[CLI\DefaultTableFields(fields: ['module', 'update_id', 'type', 'description'])]
#[CLI\FilterDefaultField(field: 'type')]
Expand All @@ -127,6 +128,17 @@ public function updatedbStatus($options = ['format' => 'table']): ?RowsOfFields
if (empty($pending)) {
$this->logger()->success(dt("No database updates required."));
} else {
if (empty($options['filter'])) {
// Show only allowed updates by default.
// Would ideally set a default filter in the parameter, however
// there's an upstream issue in
// https://github.com/consolidation/filter-via-dot-access-data/pull/51
// that needs to be addressed before that's possible, so
// manually handling the filter for now.
$pending = array_filter($pending, static function ($update_hook) {
return empty($update_hook['allowed']) || $update_hook['allowed'] === 'yes';
});
}
$return = new RowsOfFields($pending);
}
return $return;
Expand Down Expand Up @@ -494,28 +506,53 @@ public function getUpdatedbStatus(array $options): array
require_once DRUPAL_ROOT . '/core/includes/update.inc';
$pending = \update_get_update_list();

$start = $this->getUpdateList();
// Resolve any update dependencies to determine the actual updates that will
// be run and the order they will be run in.
$upcoming_updates = update_resolve_dependencies($start);

$return = [];
$warnings = [];

// Ensure system module's updates run first.
$start['system'] = [];

foreach ($pending as $module => $updates) {
if (isset($updates['start'])) {
$start[$module] = $updates['start'];
foreach ($updates['pending'] as $update_id => $description) {
// Strip cruft from front.
$description = str_replace($update_id . ' - ', '', $description);
$return[$module . "_update_$update_id"] = [
'module' => $module,
'update_id' => $update_id,
'description' => $description,
'type' => 'hook_update_n'
];
foreach ($upcoming_updates as $upcoming_update) {
$module = $upcoming_update['module'];
$update_id = $upcoming_update['number'];
$description = $pending[$module]['pending'][$update_id];
// Strip cruft from front.
$description = str_replace($update_id . ' - ', '', $description);
$module_update_function = $module . "_update_$update_id";
$return[$module_update_function] = [
'module' => $module,
'update_id' => $update_id,
'description' => $description,
'type' => 'hook_update_n',
'allowed' => !empty($upcoming_update['allowed']) ? 'yes' : 'no',
];
if (empty($upcoming_update['allowed'])) {
if ($upcoming_update['missing_dependencies']) {
// This should rarely happen, but the user should be notified
// since skipping them can potentially put the database in an
// inconsistent state.
$missing_warning = dt('Skipping @update_function due to missing dependencies: @missing_dependencies.', [
'@update_function' => "{$module_update_function}()",
'@missing_dependencies' => implode('(), ', $upcoming_update['missing_dependencies']) . '()',
]);
} else {
$missing_warning = dt("Skipping @update_function due to an error in the module's code.", [
'@update_function' => "{$module_update_function}()",
]);
}
if (isset($pending[$module]['warning'])) {
$pending[$module]['warning'] .= "\n$missing_warning";
} else {
$pending[$module]['warning'] = $missing_warning;
}
}
if (isset($updates['warning'])) {
$warnings[$module] = $updates['warning'];
if (isset($pending[$module]['warning'])) {
$warnings[$module] = $pending[$module]['warning'];
}
}

Expand All @@ -531,7 +568,8 @@ public function getUpdatedbStatus(array $options): array
'module' => $module,
'update_id' => $id,
'description' => trim($item),
'type' => 'post-update'
'type' => 'post-update',
'allowed' => 'yes',
];
}
}
Expand Down
14 changes: 14 additions & 0 deletions sut/modules/unish/drush_empty_module/drush_empty_module.install
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,17 @@ function drush_empty_module_requirements($phase) {
function drush_empty_module_update_8001() {
return 'The update ran';
}

/**
* Fake update hook 2.
*/
function drush_empty_module_update_8002() {
return 'The second update ran';
}

/**
* Fake update hook 3.
*/
function drush_empty_module_update_8003() {
return 'The third update ran';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Missing Drush update
type: module
description: Module to always trigger a missing update dependency.
core_version_requirement: '>=8'
package: Other
dependencies: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* @file
* Provides install and update functions for drush_missing_update_dependency.
*/

/**
* Implements hook_update_dependencies().
*/
function drush_missing_update_dependency_update_dependencies() {
// Flag that update hooks in this module will never resolve due to the
// missing "drush_non_existent_update_dependency" module dependency.
$dependencies['drush_missing_update_dependency'][8001] = [
'drush_non_existent_update_dependency' => 8001,
];
$dependencies['drush_missing_update_dependency'][8002] = [
'drush_non_existent_update_dependency' => 8002,
];
return $dependencies;
}


/**
* This should never have run (missing dependency).
*/
function drush_missing_update_dependency_update_8001() {
throw new \LogicException('This update function is not allowed to run, since the schema version should already be at least 8001.');
}

/**
* This should never run (missing dependency).
*/
function drush_missing_update_dependency_update_8002() {
throw new \LogicException('This update function is not allowed to run, since it has a direct dependency on a missing update.');
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Missing Drush update dependency 1
type: module
description: Module to trigger missing update dependency.
core_version_requirement: '>=8'
package: Other
dependencies: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* @file
* Provides install and update functions for drush_missing_update_dependency1.
*/

/**
* Update hook 1.
*/
function drush_missing_update_dependency1_update_8001() {
return 'The first update ran';
}

/**
* Update hook 2.
*/
function drush_missing_update_dependency1_update_8002() {
return 'The second update ran';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Missing Drush update dependency 2
type: module
description: Module to trigger missing update dependency.
core_version_requirement: '>=8'
package: Other
dependencies: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* @file
* Provides install and update functions for drush_missing_update_dependency2.
*/

/**
* Update hook 1.
*/
function drush_missing_update_dependency2_update_8001() {
return 'The first update ran';
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Drush update dependency
type: module
description: Module with hook_update_dependencies() entry.
core_version_requirement: '>=8'
package: Other
dependencies: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* @file
* Provides install and update functions for drush_update_dependency.
*/

/**
* Implements hook_update_dependencies().
*/
function drush_update_dependency_update_dependencies() {
// When this module is enabled, we are declaring here that modules run
// updates in the following order:
// 1. drush_empty_module_update_8001()
// 2. drush_update_dependency_update_8001()
// 3. drush_update_dependency_update_8002()
// ...
// 7. drush_empty_module_update_8002()
$dependencies['drush_update_dependency'][8001] = [
'drush_empty_module' => 8001,
];

// These are coordinated with the corresponding dependencies declared in
// update_test_1_update_dependencies().
$dependencies['drush_missing_update_dependency1'][8002] = [
'drush_update_dependency' => 8002,
];
// Ensure the two update hooks won't run until the module exists.
$dependencies['drush_update_dependency'][8003] = [
'drush_missing_update_dependency1' => 8001,
];
$dependencies['drush_update_dependency'][8004] = [
'drush_missing_update_dependency2' => 8001,
];

return $dependencies;
}

/**
* Dependency update hook 1.
*/
function drush_update_dependency_update_8001() {
return 'The first update ran';
}

/**
* Dependency update hook 2.
*/
function drush_update_dependency_update_8002() {
return 'The second update ran';
}

/**
* Dependency update hook 3.
*/
function drush_update_dependency_update_8003() {
return 'The third update ran';
}

/**
* Dependency update hook 4.
*/
function drush_update_dependency_update_8004() {
return 'The fourth update ran';
}

/**
* Dependency update hook 5 (blocked).
*/
function drush_update_dependency_update_8005() {
// This will not be ran until the previous hooks have been successfully ran.
return 'The fifth update ran';
}
Loading