Skip to content

Commit 21c6628

Browse files
Improve Xcode build path parsing and add workspace build test
Co-authored-by: web <web@cameroncooke.com>
1 parent e609e68 commit 21c6628

File tree

3 files changed

+59
-19
lines changed

3 files changed

+59
-19
lines changed

src/mcp/tools/device/__tests__/build_device.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,58 @@ describe('build_device plugin', () => {
135135
expect(result.content[0].text).toContain('✅ iOS Device Build build succeeded');
136136
});
137137

138+
it('should verify workspace command generation with mock executor', async () => {
139+
const commandCalls: Array<{
140+
args: string[];
141+
logPrefix: string;
142+
silent: boolean;
143+
timeout: number | undefined;
144+
}> = [];
145+
146+
const stubExecutor = async (
147+
args: string[],
148+
logPrefix: string,
149+
silent: boolean,
150+
timeout?: number,
151+
) => {
152+
commandCalls.push({ args, logPrefix, silent, timeout });
153+
return {
154+
success: true,
155+
output: 'Build succeeded',
156+
error: undefined,
157+
process: { pid: 12345 },
158+
};
159+
};
160+
161+
await buildDeviceLogic(
162+
{
163+
workspacePath: '/path/to/MyProject.xcworkspace',
164+
scheme: 'MyScheme',
165+
},
166+
stubExecutor,
167+
);
168+
169+
expect(commandCalls).toHaveLength(1);
170+
expect(commandCalls[0]).toEqual({
171+
args: [
172+
'xcodebuild',
173+
'-workspace',
174+
'/path/to/MyProject.xcworkspace',
175+
'-scheme',
176+
'MyScheme',
177+
'-configuration',
178+
'Debug',
179+
'-skipMacroValidation',
180+
'-destination',
181+
'generic/platform=iOS',
182+
'build',
183+
],
184+
logPrefix: 'iOS Device Build',
185+
silent: true,
186+
timeout: undefined,
187+
});
188+
});
189+
138190
it('should verify command generation with mock executor', async () => {
139191
const commandCalls: Array<{
140192
args: string[];

src/mcp/tools/device/get_device_app_path.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import { z } from 'zod';
9-
import { ToolResponse } from '../../../types/common.js';
9+
import { ToolResponse, XcodePlatform } from '../../../types/common.js';
1010
import { log } from '../../../utils/index.js';
1111
import { createTextResponse } from '../../../utils/index.js';
1212
import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js';
@@ -42,18 +42,6 @@ const getDeviceAppPathSchema = baseSchema
4242
// Use z.infer for type safety
4343
type GetDeviceAppPathParams = z.infer<typeof getDeviceAppPathSchema>;
4444

45-
const XcodePlatform = {
46-
iOS: 'iOS',
47-
watchOS: 'watchOS',
48-
tvOS: 'tvOS',
49-
visionOS: 'visionOS',
50-
iOSSimulator: 'iOS Simulator',
51-
watchOSSimulator: 'watchOS Simulator',
52-
tvOSSimulator: 'tvOS Simulator',
53-
visionOSSimulator: 'visionOS Simulator',
54-
macOS: 'macOS',
55-
};
56-
5745
export async function get_device_app_pathLogic(
5846
params: GetDeviceAppPathParams,
5947
executor: CommandExecutor,
@@ -81,7 +69,7 @@ export async function get_device_app_pathLogic(
8169
command.push('-workspace', params.workspacePath);
8270
} else {
8371
// This should never happen due to schema validation
84-
throw new Error('Neither projectPath nor workspacePath provided');
72+
throw new Error('Either projectPath or workspacePath is required.');
8573
}
8674

8775
// Add the scheme and configuration
@@ -117,8 +105,8 @@ export async function get_device_app_pathLogic(
117105
}
118106

119107
const buildSettingsOutput = result.output;
120-
const builtProductsDirMatch = buildSettingsOutput.match(/BUILT_PRODUCTS_DIR = (.+)$/m);
121-
const fullProductNameMatch = buildSettingsOutput.match(/FULL_PRODUCT_NAME = (.+)$/m);
108+
const builtProductsDirMatch = buildSettingsOutput.match(/^\s*BUILT_PRODUCTS_DIR\s*=\s*(.+)$/m);
109+
const fullProductNameMatch = buildSettingsOutput.match(/^\s*FULL_PRODUCT_NAME\s*=\s*(.+)$/m);
122110

123111
if (!builtProductsDirMatch || !fullProductNameMatch) {
124112
return createTextResponse(

src/mcp/tools/macos/get_macos_app_path.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export async function get_macos_app_pathLogic(
7474
command.push('-workspace', params.workspacePath);
7575
} else {
7676
// This should never happen due to schema validation
77-
throw new Error('Neither projectPath nor workspacePath provided');
77+
throw new Error('Either projectPath or workspacePath is required.');
7878
}
7979

8080
// Add the scheme and configuration
@@ -125,8 +125,8 @@ export async function get_macos_app_pathLogic(
125125
}
126126

127127
const buildSettingsOutput = result.output;
128-
const builtProductsDirMatch = buildSettingsOutput.match(/BUILT_PRODUCTS_DIR = (.+)$/m);
129-
const fullProductNameMatch = buildSettingsOutput.match(/FULL_PRODUCT_NAME = (.+)$/m);
128+
const builtProductsDirMatch = buildSettingsOutput.match(/^\s*BUILT_PRODUCTS_DIR\s*=\s*(.+)$/m);
129+
const fullProductNameMatch = buildSettingsOutput.match(/^\s*FULL_PRODUCT_NAME\s*=\s*(.+)$/m);
130130

131131
if (!builtProductsDirMatch || !fullProductNameMatch) {
132132
return {

0 commit comments

Comments
 (0)