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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ wp datamachine-code gitsync submit docs --message="Update docs"

# Workspace
wp datamachine-code workspace path
wp datamachine-code workspace path repo-name@fix-foo
wp datamachine-code workspace list
wp datamachine-code workspace clone https://github.com/org/repo.git
wp datamachine-code workspace show repo-name
Expand Down
20 changes: 19 additions & 1 deletion inc/Abilities/WorkspaceAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,15 @@ private function registerAbilities(): void {
'datamachine-code/workspace-path',
array(
'label' => 'Get Workspace Path',
'description' => 'Get the agent workspace directory path. Optionally create the directory.',
'description' => 'Get the agent workspace root path, or the path for a workspace repository handle.',
'category' => 'datamachine-code-workspace',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'name' => array(
'type' => 'string',
'description' => 'Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.',
),
'ensure' => array(
'type' => 'boolean',
'description' => 'Create the workspace directory if it does not exist.',
Expand Down Expand Up @@ -2394,6 +2398,20 @@ private function registerAbilities(): void {
* @return array Result.
*/
public static function getPath( array $input ): array|\WP_Error {
if ( ! empty($input['name']) ) {
$result = self::showRepo(array( 'name' => (string) $input['name'] ));
if ( is_wp_error($result) ) {
return $result;
}

$path = (string) ( $result['path'] ?? '' );
return array(
'success' => true,
'path' => $path,
'exists' => '' !== $path && ( RemoteWorkspaceBackend::should_handle() || is_dir($path) ),
);
}

$workspace = new Workspace();

if ( ! empty($input['ensure']) ) {
Expand Down
17 changes: 13 additions & 4 deletions inc/Cli/Commands/WorkspaceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class WorkspaceCommand extends BaseCommand {
*
* ## OPTIONS
*
* [<name>]
* : Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.
*
* [--ensure]
* : Create the directory if it doesn't exist.
*
Expand All @@ -53,6 +56,9 @@ class WorkspaceCommand extends BaseCommand {
* # Show workspace path
* wp datamachine-code workspace path
*
* # Show path for a workspace repo or worktree
* wp datamachine-code workspace path my-plugin@fix-foo
*
* # Show path and create if missing
* wp datamachine-code workspace path --ensure
*
Expand All @@ -65,11 +71,14 @@ public function path( array $args, array $assoc_args ): void {
return;
}

$result = $ability->execute(
array(
'ensure' => ! empty($assoc_args['ensure']),
)
$input = array(
'ensure' => ! empty($assoc_args['ensure']),
);
if ( ! empty($args[0]) ) {
$input['name'] = (string) $args[0];
}

$result = $ability->execute($input);

if ( is_wp_error($result) ) {
WP_CLI::error($result->get_error_message());
Expand Down
4 changes: 4 additions & 0 deletions inc/Tools/WorkspaceTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,10 @@ public function getPathDefinition(): array
'parameters' => array(
'type' => 'object',
'properties' => array(
'name' => array(
'type' => 'string',
'description' => 'Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.',
),
'ensure' => array(
'type' => 'boolean',
'description' => 'Create the workspace directory if it does not exist (default false).',
Expand Down
1 change: 1 addition & 0 deletions tests/smoke-workspace-list-repo-filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ function is_wp_error( $thing ): bool
}
}

include __DIR__ . '/../inc/Workspace/WorkspaceAliasResolver.php';
include __DIR__ . '/../inc/Workspace/Workspace.php';

$failures = 0;
Expand Down
119 changes: 119 additions & 0 deletions tests/smoke-workspace-path-cli.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
/**
* Smoke test for workspace path CLI routing.
*
* Run: php tests/smoke-workspace-path-cli.php
*
* @package DataMachineCode\Tests
*/

declare( strict_types=1 );

namespace {
if (! defined('ABSPATH') ) {
define('ABSPATH', __DIR__);
}

class WP_CLI
{
public static array $logs = array();
public static array $successes = array();

public static function error( string $message ): void
{
throw new RuntimeException($message);
}

public static function success( string $message ): void
{
self::$successes[] = $message;
}

public static function log( string $message ): void
{
self::$logs[] = $message;
}

public static function warning( string $message ): void
{
self::$logs[] = 'warning: ' . $message;
}
}

function is_wp_error( $_value ): bool
{
return false;
}

function wp_get_ability( string $name )
{
return $GLOBALS['__abilities'][ $name ] ?? null;
}
}

namespace DataMachine\Cli {
class BaseCommand
{
protected function format_items( array $items, array $fields, array $assoc_args, string $default_sort = '' ): void
{
\WP_CLI::log('table:' . count($items) . ':' . implode(',', $fields));
}
}
}

namespace {
include_once dirname(__DIR__) . '/inc/Cli/Commands/WorkspaceCommand.php';

function datamachine_code_workspace_path_cli_assert( bool $condition, string $message ): void
{
if ($condition ) {
echo " [PASS] {$message}\n";
return;
}
echo " [FAIL] {$message}\n";
exit(1);
}

class FakeWorkspacePathAbility
{
public array $last_input = array();

public function execute( array $input ): array
{
$this->last_input = $input;
$name = (string) ( $input['name'] ?? '' );

return array(
'success' => true,
'path' => '' === $name ? '/workspace' : '/workspace/' . $name,
'exists' => true,
);
}
}

echo "=== smoke-workspace-path-cli ===\n";

$ability = new FakeWorkspacePathAbility();
$GLOBALS['__abilities']['datamachine-code/workspace-path'] = $ability;
$command = new \DataMachineCode\Cli\Commands\WorkspaceCommand();

echo "\n[1] workspace path without a handle keeps root behavior\n";
WP_CLI::$logs = array();
$command->path(array(), array());
datamachine_code_workspace_path_cli_assert('/workspace' === ( WP_CLI::$logs[0] ?? null ), 'prints workspace root path');
datamachine_code_workspace_path_cli_assert(array( 'ensure' => false ) === $ability->last_input, 'root path sends only ensure flag');

echo "\n[2] workspace path accepts a primary repo handle\n";
WP_CLI::$logs = array();
$command->path(array( 'my-plugin' ), array());
datamachine_code_workspace_path_cli_assert('/workspace/my-plugin' === ( WP_CLI::$logs[0] ?? null ), 'prints primary checkout path');
datamachine_code_workspace_path_cli_assert('my-plugin' === ( $ability->last_input['name'] ?? null ), 'primary handle is passed to ability');

echo "\n[3] workspace path accepts a worktree handle\n";
WP_CLI::$logs = array();
$command->path(array( 'my-plugin@fix-foo' ), array());
datamachine_code_workspace_path_cli_assert('/workspace/my-plugin@fix-foo' === ( WP_CLI::$logs[0] ?? null ), 'prints worktree checkout path');
datamachine_code_workspace_path_cli_assert('my-plugin@fix-foo' === ( $ability->last_input['name'] ?? null ), 'worktree handle is passed to ability');

echo "\nResult: all passed\n";
}
Loading