(
params: { workspacePath?: string; projectPath?: string; scheme: string },
fileSystemExecutor: FileSystemExecutor,
)
| 116 | } |
| 117 | |
| 118 | async function findSchemePath( |
| 119 | params: { workspacePath?: string; projectPath?: string; scheme: string }, |
| 120 | fileSystemExecutor: FileSystemExecutor, |
| 121 | ): Promise<string | null> { |
| 122 | const candidates: string[] = []; |
| 123 | |
| 124 | if (params.projectPath) { |
| 125 | candidates.push( |
| 126 | path.join(params.projectPath, 'xcshareddata', 'xcschemes', `${params.scheme}.xcscheme`), |
| 127 | ); |
| 128 | } |
| 129 | |
| 130 | if (params.workspacePath) { |
| 131 | candidates.push( |
| 132 | path.join(params.workspacePath, 'xcshareddata', 'xcschemes', `${params.scheme}.xcscheme`), |
| 133 | ); |
| 134 | |
| 135 | const workspaceDir = path.dirname(params.workspacePath); |
| 136 | const workspaceDataPath = path.join(params.workspacePath, 'contents.xcworkspacedata'); |
| 137 | try { |
| 138 | const workspaceData = await fileSystemExecutor.readFile(workspaceDataPath, 'utf8'); |
| 139 | const matches = [...workspaceData.matchAll(/<FileRef\s+location\s*=\s*"([^"]+)"/g)]; |
| 140 | for (const match of matches) { |
| 141 | const resolved = resolveContainerReference(match[1], workspaceDir); |
| 142 | if (resolved.endsWith('.xcodeproj')) { |
| 143 | candidates.push( |
| 144 | path.join(resolved, 'xcshareddata', 'xcschemes', `${params.scheme}.xcscheme`), |
| 145 | ); |
| 146 | } |
| 147 | } |
| 148 | } catch { |
| 149 | // workspace data file not found; skip |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | for (const candidate of candidates) { |
| 154 | try { |
| 155 | await fileSystemExecutor.stat(candidate); |
| 156 | return candidate; |
| 157 | } catch { |
| 158 | continue; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | return null; |
| 163 | } |
| 164 | |
| 165 | function parseSchemeTargets(schemeContent: string): ReferencedTestTarget[] { |
| 166 | const targets: ReferencedTestTarget[] = []; |
no test coverage detected