Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ struct UnusedImportRuleExamples {
"allowed_transitive_imports": ["CoreFoundation", "Dispatch"],
] as [String: any Sendable],
],
] as [String: any Sendable], testMultiByteOffsets: false, testOnLinux: false):
] as [String: any Sendable], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false):
Example("""
import Foundation
typealias Foo = CFArray
Expand All @@ -202,7 +202,7 @@ struct UnusedImportRuleExamples {
dispatchMain()
""", configuration: [
"require_explicit_imports": true
], testMultiByteOffsets: false, testOnLinux: false):
], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false):
Example("""
import CoreFoundation
import Dispatch
Expand Down Expand Up @@ -236,7 +236,7 @@ struct UnusedImportRuleExamples {
class A {}
""", configuration: [
"require_explicit_imports": true
], testMultiByteOffsets: false, testOnLinux: false):
], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false):
Example("""
import CoreFoundation
import Foundation
Expand Down
4 changes: 4 additions & 0 deletions Source/SwiftLintCore/Models/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public struct Example: Sendable {
package private(set) var testDisableCommand: Bool
/// Whether the example should be tested on Linux
public private(set) var testOnLinux: Bool
/// Whether the example should be tested on Windows
public private(set) var testOnWindows: Bool
/// The path to the file where the example was created
public private(set) var file: StaticString
/// The line in the file where the example was created
Expand Down Expand Up @@ -68,13 +70,15 @@ public extension Example {
testWrappingInString: Bool = true,
testDisableCommand: Bool = true,
testOnLinux: Bool = true,
testOnWindows: Bool = true,
file: StaticString = #filePath,
line: UInt = #line,
excludeFromDocumentation: Bool = false) {
self.code = code
self.configuration = configuration
self.testMultiByteOffsets = testMultiByteOffsets
self.testOnLinux = testOnLinux
self.testOnWindows = testOnWindows
self.file = file
self.line = line
self.excludeFromDocumentation = excludeFromDocumentation
Expand Down
69 changes: 65 additions & 4 deletions Tests/TestHelpers/TestHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,45 @@ import XCTest

import SwiftLintFramework

#if os(Windows)
private struct PlatformInfo {
struct DefaultProperties {
let versionXCTest: String
let versionSwiftTesting: String
let swiftFlags: [String]?
}

let defaults: DefaultProperties
}

extension PlatformInfo.DefaultProperties: Decodable {
enum CodingKeys: String, CodingKey {
case versionXCTest = "XCTEST_VERSION"
case versionSwiftTesting = "SWIFT_TESTING_VERSION"
case swiftFlags = "SWIFTC_FLAGS"
}
}

extension PlatformInfo: Decodable {
enum CodingKeys: String, CodingKey {
case defaults = "DefaultProperties"
}
}

private let info: PlatformInfo = {
let sdk = URL(fileURLWithPath: sdkPath(), isDirectory: true)
.deletingLastPathComponent()
.deletingLastPathComponent()
.deletingLastPathComponent()
.appendingPathComponent("Info.plist")
guard let data = try? Data(contentsOf: sdk),
let info = try? PropertyListDecoder().decode(PlatformInfo.self, from: data) else {
fatalError("invalid platorm SDK - couldn't decode \(sdk.path)")
}
return info
}()
#endif

// swiftlint:disable file_length

private let violationMarker = "↓"
Expand All @@ -28,12 +67,29 @@ private extension SwiftLintFile {
.appendingPathComponent("Library")
.appendingPathComponent("Frameworks")
.path
return [
"-F",
frameworks,

let arguments = [
"-F", frameworks,
"-sdk", sdk,
"-j4", path!,
"-Xfrontend", "-enable-objc-interop",
"-j4",
path!,
]
#if os(Windows)
let XCTestPath = URL(fileURLWithPath: sdk, isDirectory: true)
.deletingLastPathComponent()
.deletingLastPathComponent()
.appendingPathComponent("Library")
.appendingPathComponent("XCTest-\(info.defaults.versionXCTest)")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use

Suggested change
.appendingPathComponent("XCTest-\(info.defaults.versionXCTest)")
.appendingPathComponent("XCTest-\(SwiftVersion.current.rawValue)")

here which directly interacts with SourceKit to retrieve the version. Not sure whether it's safe to assume that Swift version == XCTest version, though. For the 6.2.1 toolchain, that's the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that is entirely safe to assume (though it does currently hold). That is the reason for the deserialisation of the plist - it encodes the information for the SDK itself which is embedded at build time.

.appendingPathComponent("usr")
.appendingPathComponent("lib")
.appendingPathComponent("swift")
.appendingPathComponent("windows")
.path
return ["-I", XCTestPath] + arguments
#else
return arguments
#endif
}
}

Expand Down Expand Up @@ -265,6 +321,11 @@ private func testCorrection(_ correction: (Example, Example),
guard correction.0.testOnLinux else {
return
}
#endif
#if os(Windows)
guard correction.0.testOnWindows else {
return
}
#endif
var config = configuration
if let correctionConfiguration = correction.0.configuration,
Expand Down