-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Refactor Exclude by behavior into a Strategy pattern #6166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,35 @@ | ||||||
import Foundation | ||||||
|
||||||
/// Returns an array of file paths after removing the excluded paths as defined by this configuration. | ||||||
/// | ||||||
/// - parameter fileManager: The lintable file manager to use to expand the excluded paths into all matching paths. | ||||||
/// - parameter paths: The input paths to filter. | ||||||
/// | ||||||
/// - returns: The input paths after removing the excluded paths. | ||||||
struct ExcludeByPathsByExpandingSubPaths: ExcludeByStrategy { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
let excludedPaths: [String] | ||||||
|
||||||
init(configuration: Configuration, fileManager: some LintableFileManager = FileManager.default) { | ||||||
self.excludedPaths = configuration.excludedPaths | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can call the other |
||||||
.flatMap(Glob.resolveGlob) | ||||||
.parallelFlatMap { fileManager.filesToLint(inPath: $0, rootDirectory: configuration.rootDirectory) } | ||||||
} | ||||||
|
||||||
init(_ excludedPaths: [String]) { | ||||||
self.excludedPaths = excludedPaths | ||||||
} | ||||||
|
||||||
func filterExcludedPaths(in paths: [String]...) -> [String] { | ||||||
let allPaths = paths.flatMap { $0 } | ||||||
#if os(Linux) | ||||||
let result = NSMutableOrderedSet(capacity: allPaths.count) | ||||||
result.addObjects(from: allPaths) | ||||||
#else | ||||||
let result = NSMutableOrderedSet(array: allPaths) | ||||||
#endif | ||||||
|
||||||
result.minusSet(Set(excludedPaths)) | ||||||
// swiftlint:disable:next force_cast | ||||||
return result.map { $0 as! String } | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,19 @@ | ||||||||||
/// Returns the file paths that are excluded by this configuration using filtering by absolute path prefix. | ||||||||||
/// | ||||||||||
/// For cases when excluded directories contain many lintable files (e. g. Pods) it works faster than default | ||||||||||
/// algorithm `filterExcludedPaths`. | ||||||||||
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
/// | ||||||||||
/// - returns: The input paths after removing the excluded paths. | ||||||||||
struct ExcludeByPrefixStrategy: ExcludeByStrategy { | ||||||||||
let excludedPaths: [String] | ||||||||||
|
||||||||||
func filterExcludedPaths(in paths: [String]...) -> [String] { | ||||||||||
let allPaths = paths.flatMap { $0 } | ||||||||||
let excludedPaths = self.excludedPaths | ||||||||||
.parallelFlatMap { @Sendable in Glob.resolveGlob($0) } | ||||||||||
.map { $0.absolutePathStandardized() } | ||||||||||
return allPaths.filter { path in | ||||||||||
!excludedPaths.contains { path.hasPrefix($0) } | ||||||||||
} | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
public protocol ExcludeByStrategy { | ||
func filterExcludedPaths(in paths: [String]...) -> [String] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Foundation | ||
|
||
enum ExcludeByStrategyType { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The enum was only to introduce a namespace containing the factory method. We don't really need that, especially not the cases, which are sufficiently described by the two strategies conforming to the protocol. As written in the other comment, the static factory method can be part of the protocol itself via an extension. |
||
case excludeByPrefix(ExcludeByPrefixStrategy) | ||
case excludeByPathsByExpandingSubPaths(ExcludeByPathsByExpandingSubPaths) | ||
|
||
static func createExcludeByStrategy(options: LintOrAnalyzeOptions, | ||
configuration: Configuration, | ||
fileManager: some LintableFileManager = FileManager.default) | ||
-> Self { | ||
if options.useExcludingByPrefix { | ||
let strategy = ExcludeByPrefixStrategy(excludedPaths: configuration.excludedPaths) | ||
return .excludeByPrefix(strategy) | ||
} | ||
|
||
let strategy = ExcludeByPathsByExpandingSubPaths(configuration: configuration, fileManager: fileManager) | ||
return .excludeByPathsByExpandingSubPaths(strategy) | ||
} | ||
|
||
var strategy: any ExcludeByStrategy { | ||
switch self { | ||
case .excludeByPrefix(let strategy): | ||
return strategy | ||
case .excludeByPathsByExpandingSubPaths(let strategy): | ||
return strategy | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can also be
some
, can't it?