Skip to content

Commit a727e33

Browse files
committed
Add support for systemLibrary, binaryTarget, and plugin target types
1 parent e631ef7 commit a727e33

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

Sources/SwiftDependencyAuditLib/DependencyAnalyzer.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ public actor DependencyAnalyzer {
66
public init() {}
77

88
public func analyzeTarget(_ target: Target, in packageInfo: PackageInfo, customWhitelist: Set<String> = []) async throws -> AnalysisResult {
9+
// Skip source scanning for target types that don't have Swift source files
10+
if target.type == .systemLibrary || target.type == .binaryTarget {
11+
return AnalysisResult(
12+
target: target,
13+
missingDependencies: [],
14+
unusedDependencies: [],
15+
correctDependencies: [],
16+
sourceFiles: []
17+
)
18+
}
19+
920
// Scan source files for imports
1021
let sourceFiles = try await importScanner.scanDirectory(at: packageInfo.path, targetName: target.name, customWhitelist: customWhitelist)
1122

@@ -66,8 +77,9 @@ public actor DependencyAnalyzer {
6677

6778
private func getInternalModules(from packageInfo: PackageInfo, excluding currentTarget: Target) -> Set<String> {
6879
// Get names of other targets in the same package that can be imported
80+
// Exclude test targets, system libraries, and binary targets from being considered as importable modules
6981
return Set(packageInfo.targets
70-
.filter { $0.name != currentTarget.name && $0.type != .test }
82+
.filter { $0.name != currentTarget.name && $0.type != .test && $0.type != .systemLibrary && $0.type != .binaryTarget }
7183
.map { $0.name })
7284
}
7385

@@ -112,6 +124,9 @@ public actor DependencyAnalyzer {
112124
case .executable: "🔧"
113125
case .library: "📚"
114126
case .test: "🧪"
127+
case .systemLibrary: "🏛️"
128+
case .binaryTarget: "📦"
129+
case .plugin: "🔌"
115130
}
116131

117132
if !result.hasIssues && quiet {

Sources/SwiftDependencyAuditLib/Models.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public struct Target: Sendable {
1717
case executable
1818
case library
1919
case test
20+
case systemLibrary
21+
case binaryTarget
22+
case plugin
2023
}
2124
}
2225

Sources/SwiftDependencyAuditLib/PackageParser.swift

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ public actor PackageParser {
109109
let libraryRegex = /\.target\s*\(\s*name:\s*"([^"]+)"[^.]*?dependencies:\s*\[([^\]]*(?:\[[^\]]*\][^\]]*)*)\]/
110110
let testRegex = /\.testTarget\s*\(\s*name:\s*"([^"]+)"[^.]*?dependencies:\s*\[([^\]]*(?:\[[^\]]*\][^\]]*)*)\]/
111111
let macroRegex = /\.macro\s*\(\s*name:\s*"([^"]+)"[^.]*?dependencies:\s*\[([^\]]*(?:\[[^\]]*\][^\]]*)*)\]/
112+
let systemLibraryRegex = /\.systemLibrary\s*\(\s*name:\s*"([^"]+)"[^)]*\)/
113+
let binaryTargetRegex = /\.binaryTarget\s*\(\s*name:\s*"([^"]+)"[^)]*\)/
114+
let pluginRegex = /\.plugin\s*\(\s*name:\s*"([^"]+)"[^.]*?dependencies:\s*\[([^\]]*(?:\[[^\]]*\][^\]]*)*)\]/
112115

113116
// Parse executable targets
114117
for match in targetsSection.matches(of: executableRegex) {
@@ -166,9 +169,47 @@ public actor PackageParser {
166169
))
167170
}
168171

172+
// Parse system library targets (no dependencies to parse)
173+
for match in targetsSection.matches(of: systemLibraryRegex) {
174+
let name = String(match.1)
175+
176+
targets.append(Target(
177+
name: name,
178+
type: .systemLibrary,
179+
dependencies: [], // System libraries don't have Swift dependencies
180+
path: nil
181+
))
182+
}
183+
184+
// Parse binary targets (no dependencies to parse)
185+
for match in targetsSection.matches(of: binaryTargetRegex) {
186+
let name = String(match.1)
187+
188+
targets.append(Target(
189+
name: name,
190+
type: .binaryTarget,
191+
dependencies: [], // Binary targets don't have Swift dependencies
192+
path: nil
193+
))
194+
}
195+
196+
// Parse plugin targets
197+
for match in targetsSection.matches(of: pluginRegex) {
198+
let name = String(match.1)
199+
let dependenciesStr = String(match.2)
200+
let dependencies = parseDependencyList(dependenciesStr)
201+
202+
targets.append(Target(
203+
name: name,
204+
type: .plugin,
205+
dependencies: dependencies,
206+
path: nil
207+
))
208+
}
209+
169210
// Parse targets without dependencies by looking for all target declarations
170211
// and seeing which ones don't have dependency arrays
171-
let allTargetRegex = /\.(target|executableTarget|testTarget|macro)\s*\(\s*name:\s*"([^"]+)"([^)]*)\)/
212+
let allTargetRegex = /\.(target|executableTarget|testTarget|macro|plugin)\s*\(\s*name:\s*"([^"]+)"([^)]*)\)/
172213
var targetNamesWithDeps = Set<String>()
173214
for target in targets {
174215
targetNamesWithDeps.insert(target.name)
@@ -194,6 +235,8 @@ public actor PackageParser {
194235
targetType = .test
195236
case "macro":
196237
targetType = .library // Treat macros as library targets for dependency analysis
238+
case "plugin":
239+
targetType = .plugin
197240
default: // "target"
198241
targetType = .library
199242
}

0 commit comments

Comments
 (0)