Skip to content

Commit 51d3563

Browse files
authored
Merge pull request #695 from Extra-Chill/fix-694-workspace-list-classifier
fix: skip dotfile and non-git dirs in workspace list classifier (#694)
2 parents 46a005c + 319fc9f commit 51d3563

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

inc/Workspace/WorkspaceRepositoryLifecycle.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public function list_repos( ?string $repo = null, ?string $type = null ): array|
5757
continue;
5858
}
5959

60+
// Skip dotfile entries (e.g. internal infra dirs like .locks).
61+
if ( str_starts_with($entry, '.') ) {
62+
continue;
63+
}
64+
6065
$entry_path = $path . '/' . $entry;
6166
if ( ! is_dir($entry_path) ) {
6267
continue;
@@ -65,7 +70,14 @@ public function list_repos( ?string $repo = null, ?string $type = null ): array|
6570
$git_path = $entry_path . '/.git';
6671
$is_git = is_dir($git_path) || is_file($git_path);
6772
$is_wt = is_file($git_path);
68-
$parsed = $this->parse_handle($entry);
73+
74+
// A real primary or worktree always has a .git entry. Non-git
75+
// directories are not repositories and must not be emitted as rows.
76+
if ( ! $is_git ) {
77+
continue;
78+
}
79+
80+
$parsed = $this->parse_handle($entry);
6981

7082
if ( null !== $repo_filter && $parsed['repo'] !== $repo_filter ) {
7183
continue;

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,21 @@ function is_wp_error( $thing ): bool
8585
}
8686
}
8787

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

92+
exec('git --version 2>&1', $_git_version, $_git_version_exit);
93+
if ( 0 !== $_git_version_exit ) {
94+
echo "SKIP: git not available\n";
95+
exit(0);
96+
}
97+
98+
$git_init = static function ( string $dir ): void {
99+
mkdir($dir, 0755, true);
100+
exec('cd ' . escapeshellarg($dir) . ' && git init -q 2>&1');
101+
};
102+
91103
$failures = 0;
92104
$total = 0;
93105

@@ -110,15 +122,23 @@ function is_wp_error( $thing ): bool
110122

111123
echo "=== smoke-workspace-list-repo-filter ===\n";
112124

113-
mkdir($workspace_path . '/my-plugin', 0755, true);
114-
mkdir($workspace_path . '/my-plugin@feature-one', 0755, true);
115-
mkdir($workspace_path . '/data-machine-code', 0755, true);
125+
// Primaries carry a real .git directory; worktrees carry a .git file
126+
// pointing back at the primary. Non-git directories (junk) and dotfile
127+
// infra dirs (.locks) must never be listed (#694).
128+
mkdir($workspace_path, 0755, true);
129+
$git_init($workspace_path . '/my-plugin');
130+
exec('cd ' . escapeshellarg($workspace_path . '/my-plugin') . ' && git -c user.email=t@t -c user.name=t commit -q --allow-empty -m init 2>&1');
131+
exec('cd ' . escapeshellarg($workspace_path . '/my-plugin') . ' && git worktree add -q ../my-plugin@feature-one -b feature-one 2>&1');
132+
$git_init($workspace_path . '/data-machine-code');
133+
mkdir($workspace_path . '/.locks', 0755, true);
134+
file_put_contents($workspace_path . '/.locks/worktree-foo.lock', "lock\n");
135+
mkdir($workspace_path . '/junk-no-git', 0755, true);
116136

117137
$workspace = new \DataMachineCode\Workspace\Workspace();
118138

119-
echo "\n[1] Unfiltered list includes every workspace directory\n";
139+
echo "\n[1] Unfiltered list includes every git workspace directory, excludes dotfiles and non-git dirs\n";
120140
$all = $workspace->list_repos();
121-
$assert_same(array( 'data-machine-code', 'my-plugin', 'my-plugin@feature-one' ), $repo_names($all), 'unfiltered list includes all repos');
141+
$assert_same(array( 'data-machine-code', 'my-plugin', 'my-plugin@feature-one' ), $repo_names($all), 'unfiltered list includes git repos but excludes .locks and junk-no-git');
122142

123143
echo "\n[2] Repo filter includes primary checkout and worktrees\n";
124144
$filtered = $workspace->list_repos('my-plugin');
@@ -145,6 +165,11 @@ function is_wp_error( $thing ): bool
145165
$assert_same(true, is_wp_error($invalid), 'invalid type returns WP_Error');
146166
$assert_same('invalid_workspace_type', is_wp_error($invalid) ? $invalid->get_error_code() : '', 'invalid type error code is stable');
147167

168+
echo "\n[8] Primary listing never includes dotfile infra dirs or non-git directories (#694)\n";
169+
$primary_names = $repo_names($workspace->list_repos(null, 'primary'));
170+
$assert_same(false, in_array('.locks', $primary_names, true), 'dotfile dir .locks is not listed as a primary');
171+
$assert_same(false, in_array('junk-no-git', $primary_names, true), 'non-git directory is not listed as a primary');
172+
148173
echo "\nResult: " . ( $total - $failures ) . "/{$total} passed\n";
149174
exit($failures > 0 ? 1 : 0);
150175
}

0 commit comments

Comments
 (0)