diff --git a/.bazelrc b/.bazelrc index aef68378fb..12ae6e95c6 100644 --- a/.bazelrc +++ b/.bazelrc @@ -13,7 +13,6 @@ build --disk_cache=~/.bazel_cache build --experimental_remote_cache_compression build --remote_build_event_upload=minimal build --nolegacy_important_outputs -build --swiftcopt=-warnings-as-errors build:release \ --compilation_mode=opt \ diff --git a/BUILD b/BUILD index b13f510f8e..9dd4eacfee 100644 --- a/BUILD +++ b/BUILD @@ -142,33 +142,23 @@ swift_library( ":SwiftLintBuiltInRules", ":SwiftLintCore", ":SwiftLintExtraRules", + "@com_github_johnsundell_collectionconcurrencykit//:CollectionConcurrencyKit", ], ) -swift_library( - name = "swiftlint.library", +swift_binary( + name = "swiftlint", package_name = "SwiftLint", srcs = glob(["Source/swiftlint/**/*.swift"]), - copts = copts, # TODO: strict_concurrency_copts - module_name = "swiftlint", + copts = copts, visibility = ["//visibility:public"], deps = [ ":SwiftLintFramework", - "@com_github_johnsundell_collectionconcurrencykit//:CollectionConcurrencyKit", "@sourcekitten_com_github_apple_swift_argument_parser//:ArgumentParser", "@swiftlint_com_github_scottrhoyt_swifty_text_table//:SwiftyTextTable", ], ) -swift_binary( - name = "swiftlint", - copts = copts + strict_concurrency_copts, - visibility = ["//visibility:public"], - deps = [ - ":swiftlint.library", - ], -) - apple_universal_binary( name = "universal_swiftlint", binary = ":swiftlint", diff --git a/Package.swift b/Package.swift index 3b24604dfd..0dfcc60a62 100644 --- a/Package.swift +++ b/Package.swift @@ -60,7 +60,7 @@ let package = Package( .testTarget( name: "CLITests", dependencies: [ - "swiftlint" + "SwiftLintFramework", ], swiftSettings: swiftFeatures ), diff --git a/Source/swiftlint/Helpers/Benchmark.swift b/Source/SwiftLintFramework/Benchmark.swift similarity index 98% rename from Source/swiftlint/Helpers/Benchmark.swift rename to Source/SwiftLintFramework/Benchmark.swift index b05755babb..76b113155c 100644 --- a/Source/swiftlint/Helpers/Benchmark.swift +++ b/Source/SwiftLintFramework/Benchmark.swift @@ -1,5 +1,4 @@ import Foundation -import SwiftLintFramework struct BenchmarkEntry { let id: String diff --git a/Source/swiftlint/Helpers/CompilerArgumentsExtractor.swift b/Source/SwiftLintFramework/CompilerArgumentsExtractor.swift similarity index 100% rename from Source/swiftlint/Helpers/CompilerArgumentsExtractor.swift rename to Source/SwiftLintFramework/CompilerArgumentsExtractor.swift diff --git a/Source/swiftlint/Extensions/Configuration+CommandLine.swift b/Source/SwiftLintFramework/Configuration+CommandLine.swift similarity index 99% rename from Source/swiftlint/Extensions/Configuration+CommandLine.swift rename to Source/SwiftLintFramework/Configuration+CommandLine.swift index 6eb4eeb061..49e62b9a69 100644 --- a/Source/swiftlint/Extensions/Configuration+CommandLine.swift +++ b/Source/SwiftLintFramework/Configuration+CommandLine.swift @@ -1,7 +1,6 @@ import CollectionConcurrencyKit import Foundation import SourceKittenFramework -import SwiftLintFramework private actor CounterActor { private var count = 0 diff --git a/Source/swiftlint/Helpers/ExitHelper.swift b/Source/SwiftLintFramework/ExitHelper.swift similarity index 68% rename from Source/swiftlint/Helpers/ExitHelper.swift rename to Source/SwiftLintFramework/ExitHelper.swift index cd20c6a7de..f2bf1281ea 100644 --- a/Source/swiftlint/Helpers/ExitHelper.swift +++ b/Source/SwiftLintFramework/ExitHelper.swift @@ -2,8 +2,8 @@ import Glibc #endif -enum ExitHelper { - static func successfullyExit() { +package enum ExitHelper { + package static func successfullyExit() { #if os(Linux) // Workaround for https://github.com/apple/swift/issues/59961 Glibc.exit(0) diff --git a/Source/SwiftLintFramework/Exports.swift b/Source/SwiftLintFramework/Exports.swift index b61dabc36c..a352d954cd 100644 --- a/Source/SwiftLintFramework/Exports.swift +++ b/Source/SwiftLintFramework/Exports.swift @@ -6,7 +6,7 @@ private let _registerAllRulesOnceImpl: Void = { RuleRegistry.shared.register(rules: builtInRules + coreRules + extraRules()) }() -public extension RuleRegistry { +package extension RuleRegistry { /// Register all rules. Should only be called once before any SwiftLint code is executed. static func registerAllRulesOnce() { _ = _registerAllRulesOnceImpl diff --git a/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift similarity index 86% rename from Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift rename to Source/SwiftLintFramework/LintOrAnalyzeCommand.swift index 1994c12ff4..b2d313233b 100644 --- a/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift +++ b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift @@ -1,11 +1,12 @@ import Dispatch import Foundation -import SwiftLintFramework -enum LintOrAnalyzeMode { +// swiftlint:disable file_length + +package enum LintOrAnalyzeMode { case lint, analyze - var imperative: String { + package var imperative: String { switch self { case .lint: return "lint" @@ -14,7 +15,7 @@ enum LintOrAnalyzeMode { } } - var verb: String { + package var verb: String { switch self { case .lint: return "linting" @@ -24,8 +25,98 @@ enum LintOrAnalyzeMode { } } -struct LintOrAnalyzeCommand { - static func run(_ options: LintOrAnalyzeOptions) async throws { +package struct LintOrAnalyzeOptions { + let mode: LintOrAnalyzeMode + let paths: [String] + let useSTDIN: Bool + let configurationFiles: [String] + let strict: Bool + let lenient: Bool + let forceExclude: Bool + let useExcludingByPrefix: Bool + let useScriptInputFiles: Bool + let benchmark: Bool + let reporter: String? + let baseline: String? + let writeBaseline: String? + let workingDirectory: String? + let quiet: Bool + let output: String? + let progress: Bool + let cachePath: String? + let ignoreCache: Bool + let enableAllRules: Bool + let onlyRule: String? + let autocorrect: Bool + let format: Bool + let compilerLogPath: String? + let compileCommands: String? + let checkForUpdates: Bool + + package init(mode: LintOrAnalyzeMode, + paths: [String], + useSTDIN: Bool, + configurationFiles: [String], + strict: Bool, + lenient: Bool, + forceExclude: Bool, + useExcludingByPrefix: Bool, + useScriptInputFiles: Bool, + benchmark: Bool, + reporter: String?, + baseline: String?, + writeBaseline: String?, + workingDirectory: String?, + quiet: Bool, + output: String?, + progress: Bool, + cachePath: String?, + ignoreCache: Bool, + enableAllRules: Bool, + onlyRule: String?, + autocorrect: Bool, + format: Bool, + compilerLogPath: String?, + compileCommands: String?, + checkForUpdates: Bool) { + self.mode = mode + self.paths = paths + self.useSTDIN = useSTDIN + self.configurationFiles = configurationFiles + self.strict = strict + self.lenient = lenient + self.forceExclude = forceExclude + self.useExcludingByPrefix = useExcludingByPrefix + self.useScriptInputFiles = useScriptInputFiles + self.benchmark = benchmark + self.reporter = reporter + self.baseline = baseline + self.writeBaseline = writeBaseline + self.workingDirectory = workingDirectory + self.quiet = quiet + self.output = output + self.progress = progress + self.cachePath = cachePath + self.ignoreCache = ignoreCache + self.enableAllRules = enableAllRules + self.onlyRule = onlyRule + self.autocorrect = autocorrect + self.format = format + self.compilerLogPath = compilerLogPath + self.compileCommands = compileCommands + self.checkForUpdates = checkForUpdates + } + + var verb: String { + if autocorrect { + return "correcting" + } + return mode.verb + } +} + +package struct LintOrAnalyzeCommand { + package static func run(_ options: LintOrAnalyzeOptions) async throws { if let workingDirectory = options.workingDirectory { if !FileManager.default.changeCurrentDirectoryPath(workingDirectory) { throw SwiftLintError.usageError( @@ -251,42 +342,6 @@ struct LintOrAnalyzeCommand { } } -struct LintOrAnalyzeOptions { - let mode: LintOrAnalyzeMode - let paths: [String] - let useSTDIN: Bool - let configurationFiles: [String] - let strict: Bool - let lenient: Bool - let forceExclude: Bool - let useExcludingByPrefix: Bool - let useScriptInputFiles: Bool - let benchmark: Bool - let reporter: String? - let baseline: String? - let writeBaseline: String? - let workingDirectory: String? - let quiet: Bool - let output: String? - let progress: Bool - let cachePath: String? - let ignoreCache: Bool - let enableAllRules: Bool - let onlyRule: String? - let autocorrect: Bool - let format: Bool - let compilerLogPath: String? - let compileCommands: String? - let checkForUpdates: Bool - - var verb: String { - if autocorrect { - return "correcting" - } - return mode.verb - } -} - private class LintOrAnalyzeResultBuilder { var fileBenchmark = Benchmark(name: "files") var ruleBenchmark = Benchmark(name: "rules") diff --git a/Source/swiftlint/Helpers/LintableFilesVisitor.swift b/Source/SwiftLintFramework/LintableFilesVisitor.swift similarity index 99% rename from Source/swiftlint/Helpers/LintableFilesVisitor.swift rename to Source/SwiftLintFramework/LintableFilesVisitor.swift index c200513478..97c5a2e535 100644 --- a/Source/swiftlint/Helpers/LintableFilesVisitor.swift +++ b/Source/SwiftLintFramework/LintableFilesVisitor.swift @@ -1,6 +1,5 @@ import Foundation import SourceKittenFramework -import SwiftLintFramework typealias File = String typealias Arguments = [String] diff --git a/Source/swiftlint/Extensions/ProcessInfo+XcodeCloud.swift b/Source/SwiftLintFramework/ProcessInfo+XcodeCloud.swift similarity index 100% rename from Source/swiftlint/Extensions/ProcessInfo+XcodeCloud.swift rename to Source/SwiftLintFramework/ProcessInfo+XcodeCloud.swift diff --git a/Source/swiftlint/Helpers/ProgressBar.swift b/Source/SwiftLintFramework/ProgressBar.swift similarity index 98% rename from Source/swiftlint/Helpers/ProgressBar.swift rename to Source/SwiftLintFramework/ProgressBar.swift index 0d50555df6..b5a08ab62f 100644 --- a/Source/swiftlint/Helpers/ProgressBar.swift +++ b/Source/SwiftLintFramework/ProgressBar.swift @@ -1,6 +1,5 @@ import Dispatch import Foundation -import SwiftLintFramework // Inspired by https://github.com/jkandzi/Progress.swift actor ProgressBar { diff --git a/Source/swiftlint/Helpers/RulesFilter.swift b/Source/SwiftLintFramework/RulesFilter.swift similarity index 63% rename from Source/swiftlint/Helpers/RulesFilter.swift rename to Source/SwiftLintFramework/RulesFilter.swift index ad56eb29b4..9f585f7be4 100644 --- a/Source/swiftlint/Helpers/RulesFilter.swift +++ b/Source/SwiftLintFramework/RulesFilter.swift @@ -1,23 +1,25 @@ -import SwiftLintFramework +package final class RulesFilter { + package struct ExcludingOptions: OptionSet { + package let rawValue: Int -final class RulesFilter { - struct ExcludingOptions: OptionSet { - let rawValue: Int + package init(rawValue: Int) { + self.rawValue = rawValue + } - static let enabled = Self(rawValue: 1 << 0) - static let disabled = Self(rawValue: 1 << 1) - static let uncorrectable = Self(rawValue: 1 << 2) + package static let enabled = Self(rawValue: 1 << 0) + package static let disabled = Self(rawValue: 1 << 1) + package static let uncorrectable = Self(rawValue: 1 << 2) } private let allRules: RuleList private let enabledRules: [any Rule] - init(allRules: RuleList = RuleRegistry.shared.list, enabledRules: [any Rule]) { + package init(allRules: RuleList = RuleRegistry.shared.list, enabledRules: [any Rule]) { self.allRules = allRules self.enabledRules = enabledRules } - func getRules(excluding excludingOptions: ExcludingOptions) -> RuleList { + package func getRules(excluding excludingOptions: ExcludingOptions) -> RuleList { if excludingOptions.isEmpty { return allRules } diff --git a/Source/swiftlint/Helpers/Signposts.swift b/Source/SwiftLintFramework/Signposts.swift similarity index 100% rename from Source/swiftlint/Helpers/Signposts.swift rename to Source/SwiftLintFramework/Signposts.swift diff --git a/Source/swiftlint/Helpers/SwiftLintError.swift b/Source/SwiftLintFramework/SwiftLintError.swift similarity index 66% rename from Source/swiftlint/Helpers/SwiftLintError.swift rename to Source/SwiftLintFramework/SwiftLintError.swift index cf17a123a4..da6ee8fd49 100644 --- a/Source/swiftlint/Helpers/SwiftLintError.swift +++ b/Source/SwiftLintFramework/SwiftLintError.swift @@ -1,9 +1,9 @@ import Foundation -enum SwiftLintError: LocalizedError { +package enum SwiftLintError: LocalizedError { case usageError(description: String) - var errorDescription: String? { + package var errorDescription: String? { switch self { case .usageError(let description): return description diff --git a/Source/swiftlint/Helpers/SwiftPMCompilationDB.swift b/Source/SwiftLintFramework/SwiftPMCompilationDB.swift similarity index 100% rename from Source/swiftlint/Helpers/SwiftPMCompilationDB.swift rename to Source/SwiftLintFramework/SwiftPMCompilationDB.swift diff --git a/Source/swiftlint/Helpers/UpdateChecker.swift b/Source/SwiftLintFramework/UpdateChecker.swift similarity index 95% rename from Source/swiftlint/Helpers/UpdateChecker.swift rename to Source/SwiftLintFramework/UpdateChecker.swift index 15f4294b85..81043ce36b 100644 --- a/Source/swiftlint/Helpers/UpdateChecker.swift +++ b/Source/SwiftLintFramework/UpdateChecker.swift @@ -14,10 +14,9 @@ import Foundation #if canImport(FoundationNetworking) import FoundationNetworking #endif -import SwiftLintFramework -enum UpdateChecker { - static func checkForUpdates() { +package enum UpdateChecker { + package static func checkForUpdates() { guard let url = URL(string: "https://api.github.com/repos/realm/SwiftLint/releases/latest"), let data = sendRequest(to: url), let latestVersionNumber = parseVersionNumber(data) else { diff --git a/Source/swiftlint/Commands/Common/RulesFilter.ExcludingOptions+RulesFilterOptions.swift b/Source/swiftlint/Commands/Common/RulesFilter.ExcludingOptions+RulesFilterOptions.swift deleted file mode 100644 index 192bf6895a..0000000000 --- a/Source/swiftlint/Commands/Common/RulesFilter.ExcludingOptions+RulesFilterOptions.swift +++ /dev/null @@ -1,20 +0,0 @@ -extension RulesFilter.ExcludingOptions { - static func excludingOptions(byCommandLineOptions rulesFilterOptions: RulesFilterOptions) -> Self { - var excludingOptions: Self = [] - - switch rulesFilterOptions.ruleEnablement { - case .enabled: - excludingOptions.insert(.disabled) - case .disabled: - excludingOptions.insert(.enabled) - case .none: - break - } - - if rulesFilterOptions.correctable { - excludingOptions.insert(.uncorrectable) - } - - return excludingOptions - } -} diff --git a/Source/swiftlint/Commands/GenerateDocs.swift b/Source/swiftlint/Commands/GenerateDocs.swift index fc448fc594..b62e6ae8f9 100644 --- a/Source/swiftlint/Commands/GenerateDocs.swift +++ b/Source/swiftlint/Commands/GenerateDocs.swift @@ -18,7 +18,7 @@ extension SwiftLint { func run() throws { let configuration = Configuration(configurationFiles: [config].compactMap({ $0 })) let rulesFilter = RulesFilter(enabledRules: configuration.rules) - let rules = rulesFilter.getRules(excluding: .excludingOptions(byCommandLineOptions: rulesFilterOptions)) + let rules = rulesFilter.getRules(excluding: rulesFilterOptions.excludingOptions) try RuleListDocumentation(rules) .write(to: URL(fileURLWithPath: path, isDirectory: true)) diff --git a/Source/swiftlint/Commands/Rules.swift b/Source/swiftlint/Commands/Rules.swift index 33cb9bd94a..0ed3a966a7 100644 --- a/Source/swiftlint/Commands/Rules.swift +++ b/Source/swiftlint/Commands/Rules.swift @@ -40,7 +40,7 @@ extension SwiftLint { return } let rules = RulesFilter(enabledRules: configuration.rules) - .getRules(excluding: .excludingOptions(byCommandLineOptions: rulesFilterOptions)) + .getRules(excluding: rulesFilterOptions.excludingOptions) .list .sorted { $0.0 < $1.0 } if configOnly { diff --git a/Source/swiftlint/Helpers/LintOrAnalyzeArguments.swift b/Source/swiftlint/Common/LintOrAnalyzeArguments.swift similarity index 99% rename from Source/swiftlint/Helpers/LintOrAnalyzeArguments.swift rename to Source/swiftlint/Common/LintOrAnalyzeArguments.swift index 779293fdf7..8b9b00eba5 100644 --- a/Source/swiftlint/Helpers/LintOrAnalyzeArguments.swift +++ b/Source/swiftlint/Common/LintOrAnalyzeArguments.swift @@ -1,4 +1,5 @@ import ArgumentParser +import SwiftLintFramework enum LeniencyOptions: String, EnumerableFlag { case strict, lenient diff --git a/Source/swiftlint/Commands/Common/RulesFilterOptions.swift b/Source/swiftlint/Common/RulesFilterOptions.swift similarity index 51% rename from Source/swiftlint/Commands/Common/RulesFilterOptions.swift rename to Source/swiftlint/Common/RulesFilterOptions.swift index e4bfe4fb47..456bfe44d5 100644 --- a/Source/swiftlint/Commands/Common/RulesFilterOptions.swift +++ b/Source/swiftlint/Common/RulesFilterOptions.swift @@ -1,4 +1,5 @@ import ArgumentParser +import SwiftLintFramework enum RuleEnablementOptions: String, EnumerableFlag { case enabled, disabled @@ -17,4 +18,23 @@ struct RulesFilterOptions: ParsableArguments { var ruleEnablement: RuleEnablementOptions? @Flag(name: .shortAndLong, help: "Only display correctable rules") var correctable = false + + var excludingOptions: RulesFilter.ExcludingOptions { + var excludingOptions: RulesFilter.ExcludingOptions = [] + + switch ruleEnablement { + case .enabled: + excludingOptions.insert(.disabled) + case .disabled: + excludingOptions.insert(.enabled) + case .none: + break + } + + if correctable { + excludingOptions.insert(.uncorrectable) + } + + return excludingOptions + } } diff --git a/Tests/BUILD b/Tests/BUILD index 509bce099d..01aa65395c 100644 --- a/Tests/BUILD +++ b/Tests/BUILD @@ -13,7 +13,7 @@ swift_library( module_name = "CLITests", package_name = "SwiftLint", deps = [ - "//:swiftlint.library", + "//:SwiftLintFramework", ], copts = copts, ) diff --git a/Tests/CLITests/RulesFilterTests.swift b/Tests/CLITests/RulesFilterTests.swift index e3546c0810..7c2f3fcfa4 100644 --- a/Tests/CLITests/RulesFilterTests.swift +++ b/Tests/CLITests/RulesFilterTests.swift @@ -1,4 +1,3 @@ -@testable import swiftlint import SwiftLintFramework import XCTest