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
11 changes: 11 additions & 0 deletions inc/Bundle/WorkspacePreloadArtifact.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace DataMachineCode\Bundle;

use DataMachineCode\Abilities\WorkspaceAbilities;
use DataMachineCode\Workspace\RemoteWorkspaceBackend;

defined('ABSPATH') || exit;

Expand Down Expand Up @@ -179,6 +180,16 @@ private function clone_repository( array $repository ): array|\WP_Error {
$callback = $this->clone_callback ? $this->clone_callback : array( WorkspaceAbilities::class, 'cloneRepo' );
$result = call_user_func($callback, $input);

if ( is_wp_error($result) && 'datamachine_workspace_git_unavailable' === $result->get_error_code() && class_exists(RemoteWorkspaceBackend::class) ) {
$remote_result = ( new RemoteWorkspaceBackend() )->clone_repo(
$input['url'],
$input['name'] ?? null
);
if ( ! is_wp_error($remote_result) ) {
return $remote_result;
}
}

if ( is_wp_error($result) && 'repo_exists' === $result->get_error_code() ) {
$data = (array) $result->get_error_data();
if ( 'existing checkout' === (string) ( $data['state'] ?? '' ) ) {
Expand Down
16 changes: 16 additions & 0 deletions inc/Workspace/RemoteWorkspaceBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class RemoteWorkspaceBackend {
* Whether the remote backend should handle workspace operations.
*/
public static function should_handle(): bool {
if ( self::has_registered_state() ) {
return true;
}

$diagnostic = \DataMachineCode\Support\GitRunner::diagnose();
$default = self::should_handle_for_local_capabilities(
! empty($diagnostic['git_available']),
Expand All @@ -41,6 +45,18 @@ public static function should_handle_for_local_capabilities( bool $git_available
return ! ( $git_available && $streaming_available );
}

/**
* Whether remote workspace state already exists for this runtime.
*/
public static function has_registered_state(): bool {
$state = function_exists('get_option') ? get_option(self::OPTION, array()) : array();
if ( ! is_array($state) ) {
return false;
}

return ! empty($state['repos']) || ! empty($state['worktrees']);
}

/**
* Clone/register a GitHub repository as a remote workspace primary.
*
Expand Down
57 changes: 57 additions & 0 deletions tests/smoke-workspace-preload-artifact.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

declare( strict_types=1 );

namespace DataMachineCode\Abilities {
class GitHubAbilities
{
}
}

namespace {
if (! defined('ABSPATH') ) {
define('ABSPATH', __DIR__ . '/');
Expand Down Expand Up @@ -50,6 +56,25 @@ function wp_parse_url( string $url, int $component = -1 ): mixed
}
}

$GLOBALS['dmc_remote_workspace_options'] = array();

if (! function_exists('get_option') ) {
function get_option( string $key, mixed $default_value = false ): mixed
{
return $GLOBALS['dmc_remote_workspace_options'][ $key ] ?? $default_value;
}
}

if (! function_exists('update_option') ) {
function update_option( string $key, mixed $value, bool $autoload = true ): bool
{
unset($autoload);
$GLOBALS['dmc_remote_workspace_options'][ $key ] = $value;
return true;
}
}

include __DIR__ . '/../inc/Workspace/RemoteWorkspaceBackend.php';
include __DIR__ . '/../inc/Bundle/WorkspacePreloadArtifact.php';

use DataMachineCode\Bundle\WorkspacePreloadArtifact;
Expand Down Expand Up @@ -151,6 +176,38 @@ static function ( array $input ): WP_Error {
);
$assert('treats existing checkout as idempotent success', ! is_wp_error($exists) && true === ( $exists['repositories'][0]['already_exists'] ?? false ));

$remote_fallback_artifact = new WorkspacePreloadArtifact(
static function (): WP_Error {
return new WP_Error(
'datamachine_workspace_git_unavailable',
'Clone workspace repository cannot run with the current workspace backend.',
array( 'status' => 500 )
);
}
);
$remote_fallback = $remote_fallback_artifact->apply_artifact(
null,
array(
'artifact_type' => WorkspacePreloadArtifact::ARTIFACT_TYPE,
'artifact_id' => 'remote-fallback',
'payload' => array(
'repositories' => array(
array(
'name' => 'static-site-importer',
'url' => 'https://github.com/chubes4/static-site-importer.git',
),
),
),
)
);
$assert('falls back to remote backend when local git clone is unavailable', ! is_wp_error($remote_fallback) && 'github_api' === ( $remote_fallback['repositories'][0]['result']['backend'] ?? '' ));
$assert(
'remote preload state keeps remote backend active for later tools',
\DataMachineCode\Workspace\RemoteWorkspaceBackend::has_registered_state()
&& false === \DataMachineCode\Workspace\RemoteWorkspaceBackend::should_handle_for_local_capabilities(true, true)
&& \DataMachineCode\Workspace\RemoteWorkspaceBackend::should_handle()
);

if (array() !== $failures ) {
echo "\nFailures:\n";
foreach ( $failures as $failure ) {
Expand Down
Loading