Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ build:macos --crosstool_top=@local_config_apple_cc//:toolchain
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain

build --macos_minimum_os=13.5 --host_macos_minimum_os=13.5
test --macos_minimum_os=14.8 --host_macos_minimum_os=14.8 # Swift Testing libraries are compiled for macOS 14+.
build --disk_cache=~/.bazel_cache
build --experimental_remote_cache_compression
build --remote_build_event_upload=minimal
Expand Down
9 changes: 9 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"indentation" : {
"spaces" : 4
},
"lineLength": 120,
"rules" : {
"NoAccessLevelOnExtensionDeclaration": false
}
}
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.2
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ file_name:
- RuleConfigurationMacros.swift
- SwiftSyntax+SwiftLint.swift
- TestHelpers.swift
- Traits.swift
excluded_paths:
- Tests/GeneratedTests/GeneratedTests_\d\d\.swift
- Tests/FileSystemAccessTests/.+\.swift
Expand Down
4 changes: 2 additions & 2 deletions Source/SwiftLintCore/Helpers/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ public macro SwiftSyntaxRule(foldExpressions: Bool = false,
)

@attached(body)
macro TemporaryDirectory() = #externalMacro(
package macro TemporaryDirectory() = #externalMacro(
module: "SwiftLintCoreMacros",
type: "TemporaryDirectory"
)

@attached(body)
macro WorkingDirectory(path: String) = #externalMacro(
package macro WorkingDirectory(path: String) = #externalMacro(
module: "SwiftLintCoreMacros",
type: "WorkingDirectory"
)
2 changes: 1 addition & 1 deletion Source/SwiftLintCoreMacros/DisabledWithoutSourceKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ enum DisabledWithoutSourceKit: ExtensionMacro {
try ExtensionDeclSyntax("""
extension \(type) {
private static let postMessage: Void = {
Issue.genericWarning(\(raw: message)).print()
SwiftLintCore.Issue.genericWarning(\(raw: message)).print()
}()

func notifyRuleDisabledOnce() {
Expand Down
11 changes: 7 additions & 4 deletions Source/SwiftLintCoreMacros/RuleConfigurationMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ enum AutoConfigParser: MemberMacro {
}
}
return [
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws(Issue)") {
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws(SwiftLintCore.Issue)") {
for option in nonInlinedOptions {
"""
if $\(raw: option).key.isEmpty {
Expand All @@ -61,7 +61,7 @@ enum AutoConfigParser: MemberMacro {
"""
do {
try \(raw: option).apply(configuration, ruleID: Parent.identifier)
} catch let issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
} catch let issue where issue == SwiftLintCore.Issue.nothingApplied(ruleID: Parent.identifier) {
// Acceptable. Continue.
}
"""
Expand All @@ -83,7 +83,10 @@ enum AutoConfigParser: MemberMacro {
"""
if !supportedKeys.isSuperset(of: configuration.keys) {
let unknownKeys = Set(configuration.keys).subtracting(supportedKeys)
Issue.invalidConfigurationKeys(ruleID: Parent.identifier, keys: unknownKeys).print()
SwiftLintCore.Issue.invalidConfigurationKeys(
ruleID: Parent.identifier,
keys: unknownKeys
).print()
}
"""
"""
Expand Down Expand Up @@ -115,7 +118,7 @@ enum AcceptableByConfigurationElement: ExtensionMacro {
try ExtensionDeclSyntax("""
extension \(type): AcceptableByConfigurationElement {
\(raw: accessLevel)func asOption() -> OptionType { .symbol(rawValue) }
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws(Issue) {
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws(SwiftLintCore.Issue) {
if let value = value as? String, let newSelf = Self(rawValue: value) {
self = newSelf
} else {
Expand Down
20 changes: 0 additions & 20 deletions Source/SwiftLintFramework/Configuration/Configuration+Remote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ internal extension Configuration.FileGraph.FilePath {
if let mockedValue = Configuration.FileGraph.FilePath.mockedNetworkResults[urlString] {
configString = mockedValue
} else {
// Handle missing network
guard Reachability.connectivityStatus != .disconnected else {
return try handleMissingNetwork(urlString: urlString, cachedFilePath: cachedFilePath)
}

// Handle wrong url format
guard let url = URL(string: urlString) else {
throw Issue.genericWarning("Invalid configuration entry: \"\(urlString)\" isn't a valid url.")
Expand Down Expand Up @@ -117,21 +112,6 @@ internal extension Configuration.FileGraph.FilePath {
return filePath
}

private mutating func handleMissingNetwork(urlString: String, cachedFilePath: String?) throws -> String {
if let cachedFilePath {
queuedPrintError(
"warning: No internet connectivity: Unable to load remote config from \"\(urlString)\". "
+ "Using cached version as a fallback."
)
self = .existing(path: cachedFilePath)
return cachedFilePath
}
throw Issue.genericWarning(
"No internet connectivity: Unable to load remote config from \"\(urlString)\". "
+ "Also didn't found cached version to fallback to."
)
}

private mutating func handleWrongData(
urlString: String,
cachedFilePath: String?,
Expand Down
44 changes: 0 additions & 44 deletions Source/SwiftLintFramework/Helpers/Reachability.swift

This file was deleted.

6 changes: 6 additions & 0 deletions Source/SwiftLintFramework/LintOrAnalyzeCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ package struct LintOrAnalyzeOptions {
package struct LintOrAnalyzeCommand {
package static func run(_ options: LintOrAnalyzeOptions) async throws {
if let workingDirectory = options.workingDirectory {
let currentDirectory = FileManager.default.currentDirectoryPath
defer {
if !FileManager.default.changeCurrentDirectoryPath(currentDirectory) {
queuedFatalError("Could not change back to the original directory '\(currentDirectory)'.")
}
}
if !FileManager.default.changeCurrentDirectoryPath(workingDirectory) {
throw SwiftLintError.usageError(
description: """
Expand Down
10 changes: 7 additions & 3 deletions Source/swiftlint-dev/Rules+Register.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ private extension SwiftLintDev.Rules.Register {
// swiftlint:disable:next blanket_disable_command superfluous_disable_command
// swiftlint:disable single_test_class type_name

import TestHelpers
import Testing

@testable import SwiftLintBuiltInRules
@testable import SwiftLintCore
import TestHelpers

\(testClassesString)

Expand Down Expand Up @@ -189,8 +191,10 @@ private extension SwiftLintDev.Rules.Register {
let shardRules = rulesContext.shardRules(forIndex: shardIndex)

let testClasses = shardRules.map { testName in """
final class \(testName)GeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
@Suite(.rulesRegistered)
struct \(testName)GeneratedTests {
@Test
func withDefaultConfiguration() {
verifyRule(\(testName).description)
}
}
Expand Down
124 changes: 71 additions & 53 deletions Tests/BuiltInRulesTests/AttributesRuleTests.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
@testable import SwiftLintBuiltInRules
import TestHelpers
import Testing

@testable import SwiftLintBuiltInRules

final class AttributesRuleTests: SwiftLintTestCase {
func testAttributesWithAlwaysOnSameLine() {
@Suite(.rulesRegistered)
struct AttributesRuleTests {
@Test
func attributesWithAlwaysOnSameLine() {
// Test with custom `always_on_same_line`
let nonTriggeringExamples = [
Example("@objc var x: String"),
Example("@objc func foo()"),
Example("@nonobjc\n func foo()"),
Example("""
class Foo {
@objc private var object: RLMWeakObjectHandle?
@objc private var property: RLMProperty?
}
"""),
Example("""
@objc(XYZFoo) class Foo: NSObject {}
"""),
Example(
"""
class Foo {
@objc private var object: RLMWeakObjectHandle?
@objc private var property: RLMProperty?
}
"""),
Example(
"""
@objc(XYZFoo) class Foo: NSObject {}
"""),
]
let triggeringExamples = [
Example("@objc\n ↓var x: String"),
Expand All @@ -28,11 +34,13 @@ final class AttributesRuleTests: SwiftLintTestCase {
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExamples)

verifyRule(alwaysOnSameLineDescription,
ruleConfiguration: ["always_on_same_line": ["@objc"]])
verifyRule(
alwaysOnSameLineDescription,
ruleConfiguration: ["always_on_same_line": ["@objc"]])
}

func testAttributesWithAlwaysOnLineAbove() {
@Test
func attributesWithAlwaysOnLineAbove() {
// Test with custom `always_on_line_above`
let nonTriggeringExamples = [
Example("@objc\n var x: String"),
Expand All @@ -49,43 +57,49 @@ final class AttributesRuleTests: SwiftLintTestCase {
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExamples)

verifyRule(alwaysOnNewLineDescription,
ruleConfiguration: ["always_on_line_above": ["@objc"]])
verifyRule(
alwaysOnNewLineDescription,
ruleConfiguration: ["always_on_line_above": ["@objc"]])
}

func testAttributesWithAttributesOnLineAboveButOnOtherDeclaration() {
@Test
func attributesWithAttributesOnLineAboveButOnOtherDeclaration() {
let nonTriggeringExamples = [
Example("""
@IBDesignable open class TagListView: UIView {
@IBInspectable open dynamic var textColor: UIColor = UIColor.white {
didSet {}
Example(
"""
@IBDesignable open class TagListView: UIView {
@IBInspectable open dynamic var textColor: UIColor = UIColor.white {
didSet {}
}
}
}
"""),
Example("""
@objc public protocol TagListViewDelegate {
@objc optional func tagDidSelect(_ title: String, sender: TagListView)
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
}
"""),
"""),
Example(
"""
@objc public protocol TagListViewDelegate {
@objc optional func tagDidSelect(_ title: String, sender: TagListView)
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
}
"""),
]

let triggeringExamples = [
Example("""
@IBDesignable open class TagListView: UIView {
@IBInspectable
open dynamic ↓var textColor: UIColor = UIColor.white {
didSet {}
Example(
"""
@IBDesignable open class TagListView: UIView {
@IBInspectable
open dynamic ↓var textColor: UIColor = UIColor.white {
didSet {}
}
}
}
"""),
Example("""
@objc public protocol TagListViewDelegate {
@objc
optional ↓func tagDidSelect(_ title: String, sender: TagListView)
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
}
"""),
"""),
Example(
"""
@objc public protocol TagListViewDelegate {
@objc
optional ↓func tagDidSelect(_ title: String, sender: TagListView)
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
}
"""),
]

let alwaysOnNewLineDescription = AttributesRule.description
Expand All @@ -102,26 +116,29 @@ final class AttributesRuleTests: SwiftLintTestCase {
)
}

func testAttributesWithArgumentsAlwaysOnLineAboveFalse() {
@Test
func attributesWithArgumentsAlwaysOnLineAboveFalse() {
let nonTriggeringExamples = [
Example("@Environment(\\.presentationMode) private var presentationMode")
]
let triggeringExamples = [
Example("""
@Environment(\\.presentationMode)
private ↓var presentationMode
"""),
@Environment(\\.presentationMode)
private ↓var presentationMode
"""),
]

let argumentsAlwaysOnLineDescription = AttributesRule.description
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExamples)

verifyRule(argumentsAlwaysOnLineDescription,
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": false])
verifyRule(
argumentsAlwaysOnLineDescription,
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": false])
}

func testAttributesWithArgumentsAlwaysOnLineAboveTrue() {
@Test
func attributesWithArgumentsAlwaysOnLineAboveTrue() {
let nonTriggeringExamples = [
Example("@Environment(\\.presentationMode)\nprivate var presentationMode")
]
Expand All @@ -133,7 +150,8 @@ final class AttributesRuleTests: SwiftLintTestCase {
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExamples)

verifyRule(argumentsAlwaysOnLineDescription,
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": true])
verifyRule(
argumentsAlwaysOnLineDescription,
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": true])
}
}
Loading
Loading