diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dff04f3..de4f011e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Fixed + +- Fixed `swift_package_build`, `swift_package_test`, and `swift_package_clean` swallowing compiler diagnostics on failure by treating empty stderr as falsy, so stdout diagnostics are included in the error response ([#243](https://github.com/getsentry/XcodeBuildMCP/issues/243)). + ## [2.1.0] ### Added diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts index d44c25a8..7387e8fc 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts @@ -228,6 +228,32 @@ describe('swift_package_build plugin', () => { }); }); + it('should include stdout diagnostics when stderr is empty on build failure', async () => { + const executor = createMockExecutor({ + success: false, + error: '', + output: + "main.swift:10:25: error: cannot find type 'DOESNOTEXIST' in scope\nlet broken: DOESNOTEXIST = 42", + }); + + const result = await swift_package_buildLogic( + { + packagePath: '/test/package', + }, + executor, + ); + + expect(result).toEqual({ + content: [ + { + type: 'text', + text: "Error: Swift package build failed\nDetails: main.swift:10:25: error: cannot find type 'DOESNOTEXIST' in scope\nlet broken: DOESNOTEXIST = 42", + }, + ], + isError: true, + }); + }); + it('should handle spawn error', async () => { const executor = async () => { throw new Error('spawn ENOENT'); diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts index 2e12f9cd..d8a6a13a 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts @@ -218,6 +218,32 @@ describe('swift_package_test plugin', () => { }); }); + it('should include stdout diagnostics when stderr is empty on test failure', async () => { + const mockExecutor = createMockExecutor({ + success: false, + error: '', + output: + "main.swift:10:25: error: cannot find type 'DOESNOTEXIST' in scope\nlet broken: DOESNOTEXIST = 42", + }); + + const result = await swift_package_testLogic( + { + packagePath: '/test/package', + }, + mockExecutor, + ); + + expect(result).toEqual({ + content: [ + { + type: 'text', + text: "Error: Swift package tests failed\nDetails: main.swift:10:25: error: cannot find type 'DOESNOTEXIST' in scope\nlet broken: DOESNOTEXIST = 42", + }, + ], + isError: true, + }); + }); + it('should handle spawn error', async () => { const mockExecutor = async () => { throw new Error('spawn ENOENT'); diff --git a/src/mcp/tools/swift-package/swift_package_build.ts b/src/mcp/tools/swift-package/swift_package_build.ts index 96383809..2dd87d93 100644 --- a/src/mcp/tools/swift-package/swift_package_build.ts +++ b/src/mcp/tools/swift-package/swift_package_build.ts @@ -57,7 +57,7 @@ export async function swift_package_buildLogic( try { const result = await executor(['swift', ...swiftArgs], 'Swift Package Build', false, undefined); if (!result.success) { - const errorMessage = result.error ?? result.output ?? 'Unknown error'; + const errorMessage = result.error || result.output || 'Unknown error'; return createErrorResponse('Swift package build failed', errorMessage); } diff --git a/src/mcp/tools/swift-package/swift_package_clean.ts b/src/mcp/tools/swift-package/swift_package_clean.ts index 4d8b47aa..1c2e8428 100644 --- a/src/mcp/tools/swift-package/swift_package_clean.ts +++ b/src/mcp/tools/swift-package/swift_package_clean.ts @@ -26,7 +26,7 @@ export async function swift_package_cleanLogic( try { const result = await executor(['swift', ...swiftArgs], 'Swift Package Clean', false, undefined); if (!result.success) { - const errorMessage = result.error ?? result.output ?? 'Unknown error'; + const errorMessage = result.error || result.output || 'Unknown error'; return createErrorResponse('Swift package clean failed', errorMessage); } diff --git a/src/mcp/tools/swift-package/swift_package_test.ts b/src/mcp/tools/swift-package/swift_package_test.ts index 25579b1e..8d022d02 100644 --- a/src/mcp/tools/swift-package/swift_package_test.ts +++ b/src/mcp/tools/swift-package/swift_package_test.ts @@ -67,7 +67,7 @@ export async function swift_package_testLogic( try { const result = await executor(['swift', ...swiftArgs], 'Swift Package Test', false, undefined); if (!result.success) { - const errorMessage = result.error ?? result.output ?? 'Unknown error'; + const errorMessage = result.error || result.output || 'Unknown error'; return createErrorResponse('Swift package tests failed', errorMessage); }