@@ -102,11 +102,10 @@ typealias Validate = (Package, _ excludedSuffixes: [String]) -> [LocalizedError]
102102public extension Array where Element == SPMGraphConfig . Lint . Rule {
103103 /// The default lint rules for users of the spmgraph lint functionality.
104104 ///
105- /// - note: **Most default rules allow for customization**, i.e. `liveModuleLiveDependency` can be used
106- /// directly when setting up your `SPMGraphConfig.swift` and with a custom implementation of both the `isLiveModule` and
107- /// the `excludedDependencies` parameters.
105+ /// - note: **Most default rules allow for customization**, i.e. `liveModuleLiveDependency` and `unusedDependencies` can be used
106+ /// directly when setting up your `SPMGraphConfig.swift` with custom parameters such as `excludedDependencies`.
108107 static let `default` : [ SPMGraphConfig . Lint . Rule ] = [
109- . unusedDependencies,
108+ . unusedDependencies( ) ,
110109 . liveModuleLiveDependency( ) ,
111110 . baseOrInterfaceModuleLiveDependency( ) ,
112111 ]
@@ -212,61 +211,69 @@ public extension SPMGraphConfig.Lint.Rule {
212211 /// - note: For `@_exported` usages, there will be an error in case only the exported module is used.
213212 /// For example, module Networking exports module NetworkingHelpers, if only NetworkingHelpers is used by a target there will be
214213 /// a lint error, while if both Networking and NetworkingHelpers are used there will be no error.
215- static let unusedDependencies = Self (
216- id: " unusedDependencies " ,
217- name: " Unused linked dependencies " ,
218- abstract: """
219- To keep the project clean and avoid long compile times, a Module should not have any unused dependencies.
220-
221- - Note: It does blindly expects the target to match the product name, and doesn't yet consider
222- the multiple targets that compose a product (open improvement).
223-
224- - Note: For `@_exported` usages, there will be an error in case only the exported module is used.
225- For example, module Networking exports module NetworkingHelpers, if only NetworkingHelpers is used by a target
226- there will be a lint error, while if both Networking and NetworkingHelpers are used there will be no error.
227- """ ,
228- validate: { package , excludedSuffixes in
229- let errors : [ SPMGraphConfig . Lint . Error ] = package . modules
230- . filter { !$0. containsOneOf ( suffixes: excludedSuffixes) && !$0. isFeature }
231- . sorted ( )
232- . compactMap { module in
233- let dependencies = module
234- . dependenciesFilteringOutLiveInUITestSupport
235- . filter { dependency in
236- let isExcluded = dependency. containsOneOf ( suffixes: excludedSuffixes)
237- return !isExcluded && dependency. shouldBeImported
238- }
239- let swiftFiles = try ? findSwiftFiles ( in: module. path. pathString)
240-
241- return dependencies. compactMap { dependency in
242- let filePaths = swiftFiles ?? [ ]
243- var isDependencyUsed = false
244- for filePath in filePaths {
245- let fileContent = try ? String ( contentsOfFile: filePath, encoding: . utf8)
246- let regexPattern =
247- " import (enum |struct |class )?( \\ b \( NSRegularExpression . escapedPattern ( for: dependency. name) ) \\ b) "
248- if let regex = try ? NSRegularExpression ( pattern: regexPattern, options: [ ] ) {
249- let range = NSRange ( location: 0 , length: fileContent? . utf16. count ?? 0 )
250- let match = regex. firstMatch ( in: fileContent ?? " " , options: [ ] , range: range)
251- if match != nil {
252- isDependencyUsed = true
253- break
214+ ///
215+ /// - Parameters:
216+ /// - excludedDependencies: A list of dependency names that should be excluded from unused dependency checks (e.g., umbrella dependencies).
217+ static func unusedDependencies(
218+ excludedDependencies: [ String ] = [ ]
219+ ) -> Self {
220+ Self (
221+ id: " unusedDependencies " ,
222+ name: " Unused linked dependencies " ,
223+ abstract: """
224+ To keep the project clean and avoid long compile times, a Module should not have any unused dependencies.
225+
226+ - Note: It does blindly expects the target to match the product name, and doesn't yet consider
227+ the multiple targets that compose a product (open improvement).
228+
229+ - Note: For `@_exported` usages, there will be an error in case only the exported module is used.
230+ For example, module Networking exports module NetworkingHelpers, if only NetworkingHelpers is used by a target
231+ there will be a lint error, while if both Networking and NetworkingHelpers are used there will be no error.
232+ """ ,
233+ validate: { package , excludedSuffixes in
234+ let errors : [ SPMGraphConfig . Lint . Error ] = package . modules
235+ . filter { !$0. containsOneOf ( suffixes: excludedSuffixes) && !$0. isFeature }
236+ . sorted ( )
237+ . compactMap { module in
238+ let dependencies = module
239+ . dependenciesFilteringOutLiveInUITestSupport
240+ . filter { dependency in
241+ let isExcluded = dependency. containsOneOf ( suffixes: excludedSuffixes)
242+ let isExcludedDependency = excludedDependencies. contains ( dependency. name)
243+ return !isExcluded && !isExcludedDependency && dependency. shouldBeImported
244+ }
245+ let swiftFiles = try ? findSwiftFiles ( in: module. path. pathString)
246+
247+ return dependencies. compactMap { dependency in
248+ let filePaths = swiftFiles ?? [ ]
249+ var isDependencyUsed = false
250+ for filePath in filePaths {
251+ let fileContent = try ? String ( contentsOfFile: filePath, encoding: . utf8)
252+ let regexPattern =
253+ " import (enum |struct |class )?( \\ b \( NSRegularExpression . escapedPattern ( for: dependency. name) ) \\ b) "
254+ if let regex = try ? NSRegularExpression ( pattern: regexPattern, options: [ ] ) {
255+ let range = NSRange ( location: 0 , length: fileContent? . utf16. count ?? 0 )
256+ let match = regex. firstMatch ( in: fileContent ?? " " , options: [ ] , range: range)
257+ if match != nil {
258+ isDependencyUsed = true
259+ break
260+ }
254261 }
255262 }
256- }
257263
258- return isDependencyUsed
259- ? nil
260- : SPMGraphConfig . Lint. Error. unusedDependencies (
261- moduleName: module. name,
262- dependencyName: dependency. name
263- )
264+ return isDependencyUsed
265+ ? nil
266+ : SPMGraphConfig . Lint. Error. unusedDependencies (
267+ moduleName: module. name,
268+ dependencyName: dependency. name
269+ )
270+ }
264271 }
265- }
266- . flatMap { $0 }
267- return errors
268- }
269- )
272+ . flatMap { $0 }
273+ return errors
274+ }
275+ )
276+ }
270277}
271278
272279private extension SPMGraphConfig . Lint . Rule {
0 commit comments