Skip to content

Conversation

@swizzlr
Copy link

@swizzlr swizzlr commented Dec 18, 2025

Problem:
The tool produced false positives for SPM packages that use custom path: arguments in their target definitions. When Sources/TargetName didn't exist, it fell back to scanning ALL of Sources/ and attributed every file to that target.

Example: A package with:
.target(name: "MyModule", path: "Sources/Core")
.target(name: "MyModuleUI", path: "Sources/UI")

Would look for Sources/MyModule, not find it, fall back to Sources/, scan all files, and report UI code as violations for MyModule.

Solution:

  1. Added path: String? property to SwiftPackageTarget to store custom paths from target definitions

  2. Updated PackageSwiftFileVisitor to parse the path: argument from SPM target function calls using SwiftSyntax

  3. Modified PackagesParser to:

    • Use the explicit path from Package.swift when available
    • Normalize paths (strip leading/trailing slashes) to prevent double-slash issues
    • Throw customPathNotFound error if custom path doesn't exist (prevents silent false positives from scanning zero files)
    • Only fall back to convention (Sources/TargetName) when no custom path is specified

Tests:

  • Added CustomPathPackage fixture with path: "Sources/Core" for target
  • Added Sources/UI/ with undeclared import to verify files outside custom path are NOT scanned (negative test case)
  • Added testTarget with custom path (CustomTests/) to verify .testTarget() works correctly with path: argument
  • Added InvalidCustomPathPackage fixture to test customPathNotFound error

🤖 Generated with Claude Code

Problem:
The tool produced false positives for SPM packages that use custom
path: arguments in their target definitions. When Sources/TargetName
didn't exist, it fell back to scanning ALL of Sources/ and attributed
every file to that target.

Example: A package with:
  .target(name: "MyModule", path: "Sources/Core")
  .target(name: "MyModuleUI", path: "Sources/UI")

Would look for Sources/MyModule, not find it, fall back to Sources/,
scan all files, and report UI code as violations for MyModule.

Solution:
1. Added `path: String?` property to SwiftPackageTarget to store
   custom paths from target definitions

2. Updated PackageSwiftFileVisitor to parse the path: argument from
   SPM target function calls using SwiftSyntax

3. Modified PackagesParser to:
   - Use the explicit path from Package.swift when available
   - Normalize paths (strip leading/trailing slashes) to prevent
     double-slash issues
   - Throw `customPathNotFound` error if custom path doesn't exist
     (prevents silent false positives from scanning zero files)
   - Only fall back to convention (Sources/TargetName) when no
     custom path is specified

Tests:
- Added CustomPathPackage fixture with path: "Sources/Core" for target
- Added Sources/UI/ with undeclared import to verify files outside
  custom path are NOT scanned (negative test case)
- Added testTarget with custom path (CustomTests/) to verify
  .testTarget() works correctly with path: argument
- Added InvalidCustomPathPackage fixture to test customPathNotFound error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@michaelversus
Copy link
Owner

Thank you for your contribution @swizzlr !

@michaelversus michaelversus self-assigned this Dec 18, 2025
@codecov-commenter
Copy link

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@michaelversus michaelversus self-requested a review December 18, 2025 19:46
@michaelversus michaelversus merged commit a0f58d4 into michaelversus:main Dec 18, 2025
1 check passed
@swizzlr swizzlr deleted the feat/use-package-path branch December 29, 2025 12:58
@swizzlr
Copy link
Author

swizzlr commented Dec 29, 2025

No worries, thanks for taking the time to review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants