Skip to content

Commit 680abd6

Browse files
authored
Support workspace path repo handles (#627)
* Support workspace path handles * Tighten workspace path handle docs * Narrow workspace path smoke dependencies
1 parent 1f4a36e commit 680abd6

6 files changed

Lines changed: 157 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ wp datamachine-code gitsync submit docs --message="Update docs"
9696

9797
# Workspace
9898
wp datamachine-code workspace path
99+
wp datamachine-code workspace path repo-name@fix-foo
99100
wp datamachine-code workspace list
100101
wp datamachine-code workspace clone https://github.com/org/repo.git
101102
wp datamachine-code workspace show repo-name

inc/Abilities/WorkspaceAbilities.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,15 @@ private function registerAbilities(): void {
7979
'datamachine-code/workspace-path',
8080
array(
8181
'label' => 'Get Workspace Path',
82-
'description' => 'Get the agent workspace directory path. Optionally create the directory.',
82+
'description' => 'Get the agent workspace root path, or the path for a workspace repository handle.',
8383
'category' => 'datamachine-code-workspace',
8484
'input_schema' => array(
8585
'type' => 'object',
8686
'properties' => array(
87+
'name' => array(
88+
'type' => 'string',
89+
'description' => 'Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.',
90+
),
8791
'ensure' => array(
8892
'type' => 'boolean',
8993
'description' => 'Create the workspace directory if it does not exist.',
@@ -2408,6 +2412,20 @@ private function registerAbilities(): void {
24082412
* @return array Result.
24092413
*/
24102414
public static function getPath( array $input ): array|\WP_Error {
2415+
if ( ! empty($input['name']) ) {
2416+
$result = self::showRepo(array( 'name' => (string) $input['name'] ));
2417+
if ( is_wp_error($result) ) {
2418+
return $result;
2419+
}
2420+
2421+
$path = (string) ( $result['path'] ?? '' );
2422+
return array(
2423+
'success' => true,
2424+
'path' => $path,
2425+
'exists' => '' !== $path && ( RemoteWorkspaceBackend::should_handle() || is_dir($path) ),
2426+
);
2427+
}
2428+
24112429
$workspace = new Workspace();
24122430

24132431
if ( ! empty($input['ensure']) ) {

inc/Cli/Commands/WorkspaceCommand.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class WorkspaceCommand extends BaseCommand {
4545
*
4646
* ## OPTIONS
4747
*
48+
* [<name>]
49+
* : Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.
50+
*
4851
* [--ensure]
4952
* : Create the directory if it doesn't exist.
5053
*
@@ -53,6 +56,9 @@ class WorkspaceCommand extends BaseCommand {
5356
* # Show workspace path
5457
* wp datamachine-code workspace path
5558
*
59+
* # Show path for a workspace repo or worktree
60+
* wp datamachine-code workspace path my-plugin@fix-foo
61+
*
5662
* # Show path and create if missing
5763
* wp datamachine-code workspace path --ensure
5864
*
@@ -65,11 +71,14 @@ public function path( array $args, array $assoc_args ): void {
6571
return;
6672
}
6773

68-
$result = $ability->execute(
69-
array(
70-
'ensure' => ! empty($assoc_args['ensure']),
71-
)
74+
$input = array(
75+
'ensure' => ! empty($assoc_args['ensure']),
7276
);
77+
if ( ! empty($args[0]) ) {
78+
$input['name'] = (string) $args[0];
79+
}
80+
81+
$result = $ability->execute($input);
7382

7483
if ( is_wp_error($result) ) {
7584
WP_CLI::error($result->get_error_message());

inc/Tools/WorkspaceTools.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,10 @@ public function getPathDefinition(): array
10121012
'parameters' => array(
10131013
'type' => 'object',
10141014
'properties' => array(
1015+
'name' => array(
1016+
'type' => 'string',
1017+
'description' => 'Optional primary or worktree handle, such as <repo> or <repo>@<branch-slug>.',
1018+
),
10151019
'ensure' => array(
10161020
'type' => 'boolean',
10171021
'description' => 'Create the workspace directory if it does not exist (default false).',

tests/smoke-workspace-list-repo-filter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ function is_wp_error( $thing ): bool
8585
}
8686
}
8787

88+
include __DIR__ . '/../inc/Workspace/WorkspaceAliasResolver.php';
8889
include __DIR__ . '/../inc/Workspace/Workspace.php';
8990

9091
$failures = 0;

tests/smoke-workspace-path-cli.php

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
/**
3+
* Smoke test for workspace path CLI routing.
4+
*
5+
* Run: php tests/smoke-workspace-path-cli.php
6+
*
7+
* @package DataMachineCode\Tests
8+
*/
9+
10+
declare( strict_types=1 );
11+
12+
namespace {
13+
if (! defined('ABSPATH') ) {
14+
define('ABSPATH', __DIR__);
15+
}
16+
17+
class WP_CLI
18+
{
19+
public static array $logs = array();
20+
public static array $successes = array();
21+
22+
public static function error( string $message ): void
23+
{
24+
throw new RuntimeException($message);
25+
}
26+
27+
public static function success( string $message ): void
28+
{
29+
self::$successes[] = $message;
30+
}
31+
32+
public static function log( string $message ): void
33+
{
34+
self::$logs[] = $message;
35+
}
36+
37+
public static function warning( string $message ): void
38+
{
39+
self::$logs[] = 'warning: ' . $message;
40+
}
41+
}
42+
43+
function is_wp_error( $_value ): bool
44+
{
45+
return false;
46+
}
47+
48+
function wp_get_ability( string $name )
49+
{
50+
return $GLOBALS['__abilities'][ $name ] ?? null;
51+
}
52+
}
53+
54+
namespace DataMachine\Cli {
55+
class BaseCommand
56+
{
57+
protected function format_items( array $items, array $fields, array $assoc_args, string $default_sort = '' ): void
58+
{
59+
\WP_CLI::log('table:' . count($items) . ':' . implode(',', $fields));
60+
}
61+
}
62+
}
63+
64+
namespace {
65+
include_once dirname(__DIR__) . '/inc/Cli/Commands/WorkspaceCommand.php';
66+
67+
function datamachine_code_workspace_path_cli_assert( bool $condition, string $message ): void
68+
{
69+
if ($condition ) {
70+
echo " [PASS] {$message}\n";
71+
return;
72+
}
73+
echo " [FAIL] {$message}\n";
74+
exit(1);
75+
}
76+
77+
class FakeWorkspacePathAbility
78+
{
79+
public array $last_input = array();
80+
81+
public function execute( array $input ): array
82+
{
83+
$this->last_input = $input;
84+
$name = (string) ( $input['name'] ?? '' );
85+
86+
return array(
87+
'success' => true,
88+
'path' => '' === $name ? '/workspace' : '/workspace/' . $name,
89+
'exists' => true,
90+
);
91+
}
92+
}
93+
94+
echo "=== smoke-workspace-path-cli ===\n";
95+
96+
$ability = new FakeWorkspacePathAbility();
97+
$GLOBALS['__abilities']['datamachine-code/workspace-path'] = $ability;
98+
$command = new \DataMachineCode\Cli\Commands\WorkspaceCommand();
99+
100+
echo "\n[1] workspace path without a handle keeps root behavior\n";
101+
WP_CLI::$logs = array();
102+
$command->path(array(), array());
103+
datamachine_code_workspace_path_cli_assert('/workspace' === ( WP_CLI::$logs[0] ?? null ), 'prints workspace root path');
104+
datamachine_code_workspace_path_cli_assert(array( 'ensure' => false ) === $ability->last_input, 'root path sends only ensure flag');
105+
106+
echo "\n[2] workspace path accepts a primary repo handle\n";
107+
WP_CLI::$logs = array();
108+
$command->path(array( 'my-plugin' ), array());
109+
datamachine_code_workspace_path_cli_assert('/workspace/my-plugin' === ( WP_CLI::$logs[0] ?? null ), 'prints primary checkout path');
110+
datamachine_code_workspace_path_cli_assert('my-plugin' === ( $ability->last_input['name'] ?? null ), 'primary handle is passed to ability');
111+
112+
echo "\n[3] workspace path accepts a worktree handle\n";
113+
WP_CLI::$logs = array();
114+
$command->path(array( 'my-plugin@fix-foo' ), array());
115+
datamachine_code_workspace_path_cli_assert('/workspace/my-plugin@fix-foo' === ( WP_CLI::$logs[0] ?? null ), 'prints worktree checkout path');
116+
datamachine_code_workspace_path_cli_assert('my-plugin@fix-foo' === ( $ability->last_input['name'] ?? null ), 'worktree handle is passed to ability');
117+
118+
echo "\nResult: all passed\n";
119+
}

0 commit comments

Comments
 (0)