Skip to content
Merged
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
61 changes: 49 additions & 12 deletions inc/Cli/Commands/WorkspaceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -666,22 +666,59 @@ private function control_cleanup_run_job( string $operation, int $job_id, array
return;
}

$input = array( 'job_id' => $job_id );
if ( 'resume' === $operation ) {
$input['force'] = ! empty( $assoc_args['force'] );
} else {
$input['reason'] = 'cleanup_cancelled';
$target_job_ids = $this->cleanup_run_control_job_ids( $operation, $job_id );
$results = array();
foreach ( $target_job_ids as $target_job_id ) {
$input = array( 'job_id' => $target_job_id );
if ( 'resume' === $operation ) {
$input['force'] = ! empty( $assoc_args['force'] );
} else {
$input['reason'] = 'cleanup_cancelled';
}

$result = $ability->execute( $input );
if ( ! ( $result['success'] ?? false ) ) {
WP_CLI::error( (string) ( $result['error'] ?? 'Cleanup run control failed.' ) );
return;
}
$results[] = $result;
}

$result = $ability->execute( $input );
if ( ! ( $result['success'] ?? false ) ) {
WP_CLI::error( (string) ( $result['error'] ?? 'Cleanup run control failed.' ) );
return;
$output = $results[0] ?? array(
'success' => true,
'job_id' => $job_id,
);
$output['run_id'] = $this->cleanup_run_id( $job_id );
$output['state'] = 'resume' === $operation ? 'running' : 'cancelled';
$output['controlled_job_ids'] = $target_job_ids;
$output['results'] = $results;
$this->render_cleanup_control_result( $output, $assoc_args );
}

/**
* Resolve which Data Machine jobs should be controlled for a job-backed cleanup run.
*
* @param string $operation Cleanup control operation.
* @param int $job_id Cleanup parent job ID.
* @return array<int,int>
*/
private function cleanup_run_control_job_ids( string $operation, int $job_id ): array {
$output = $this->cleanup_run_evidence_store()->read( $this->cleanup_run_id( $job_id ), true, true );
if ( $output instanceof \WP_Error ) {
return array( $job_id );
}

$result['run_id'] = $this->cleanup_run_id( $job_id );
$result['state'] = 'resume' === $operation ? 'running' : 'cancelled';
$this->render_cleanup_control_result( $result, $assoc_args );
$children = (array) ( $output['evidence']['children'] ?? array() );
$processing_ids = array_map( 'intval', (array) ( $children['processing_job_ids'] ?? array() ) );
$failed_ids = array_map( 'intval', (array) ( $children['failed_job_ids'] ?? array() ) );
$pending_ids = array_map( 'intval', (array) ( $children['pending_job_ids'] ?? array() ) );

if ( 'resume' === $operation ) {
$child_targets = array_values( array_unique( array_filter( array_merge( $processing_ids, $failed_ids ) ) ) );
return array() !== $child_targets ? $child_targets : array( $job_id );
}

return array_values( array_unique( array_filter( array_merge( array( $job_id ), $pending_ids, $processing_ids ) ) ) );
}

private function render_cleanup_control_result( array $result, array $assoc_args ): void {
Expand Down
9 changes: 9 additions & 0 deletions tests/smoke-worktree-cleanup-cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,11 @@ public function execute( array $input ): array {

class FakeRetryJobAbility {
public array $last_input = array();
public array $inputs = array();

public function execute( array $input ): array {
$this->last_input = $input;
$this->inputs[] = $input;
return array(
'success' => true,
'job_id' => (int) $input['job_id'],
Expand All @@ -567,9 +569,11 @@ public function execute( array $input ): array {

class FakeFailJobAbility {
public array $last_input = array();
public array $inputs = array();

public function execute( array $input ): array {
$this->last_input = $input;
$this->inputs[] = $input;
return array(
'success' => true,
'job_id' => (int) $input['job_id'],
Expand Down Expand Up @@ -714,11 +718,16 @@ public function execute( array $input ): array {
WP_CLI::$logs = array();
WP_CLI::$successes = array();
$command->cleanup( array( 'resume', 'cleanup-run-123' ), array( 'force' => true, 'format' => 'json' ) );
$resume_json = json_decode( WP_CLI::$logs[0] ?? '', true );
datamachine_code_cleanup_assert( array( 125, 127 ) === ( $resume_json['controlled_job_ids'] ?? array() ), 'cleanup resume controls active child jobs before the parent' );
datamachine_code_cleanup_assert( true === ( $retry_job_ability->last_input['force'] ?? null ), 'cleanup resume forwards force retry flag' );
datamachine_code_cleanup_assert( array( 125, 127 ) === array_map( fn( $input ) => (int) ( $input['job_id'] ?? 0 ), $retry_job_ability->inputs ), 'cleanup resume retries processing and failed child jobs' );

WP_CLI::$logs = array();
WP_CLI::$successes = array();
$command->cleanup( array( 'cancel', 'cleanup-run-123' ), array( 'format' => 'json' ) );
$cancel_json = json_decode( WP_CLI::$logs[0] ?? '', true );
datamachine_code_cleanup_assert( array( 123, 125 ) === ( $cancel_json['controlled_job_ids'] ?? array() ), 'cleanup cancel controls parent and active child jobs' );
datamachine_code_cleanup_assert( 'cleanup_cancelled' === ( $fail_job_ability->last_input['reason'] ?? '' ), 'cleanup cancel fails job with cleanup cancellation reason' );

echo "\n[0] list stale output exposes disk fields\n";
Expand Down
Loading