Skip to content

Commit

Permalink
Adopt Strict Concurrency checking (#821)
Browse files Browse the repository at this point in the history
* Convert `var` to `let` for structured concurrency

* Add Sendable conformance to types triggering warnings

* Add strict concurrency checking to package

* Annotation `PathKit` imports with `@preconcurrency`

* Convert to a global funciton to avoid shared global state.

Darwin.glob and Glibc.glob would likely need to be marked as `@Sendable` to be able to be referenced from global scope
  • Loading branch information
waltflanagan authored May 28, 2024
1 parent 0aa43b7 commit 19f5029
Show file tree
Hide file tree
Showing 12 changed files with 31 additions and 24 deletions.
5 changes: 4 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.7
// swift-tools-version:5.9

import PackageDescription

Expand All @@ -17,6 +17,9 @@ let package = Package(
dependencies: [
.product(name: "PathKit", package: "PathKit"),
.product(name: "AEXML", package: "AEXML"),
],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")
]),
.testTarget(name: "XcodeProjTests", dependencies: ["XcodeProj"]),
]
Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Errors/Errors.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import PathKit
@preconcurrency import PathKit

// MARK: - Xcodeproj

Expand All @@ -8,7 +8,7 @@ import PathKit
/// - notFound: the project cannot be found.
/// - pbxProjNotFound: the .pbxproj file couldn't be found inside the project folder.
/// - xcworkspaceNotFound: the workspace cannot be found at the given path.
public enum XCodeProjError: Error, CustomStringConvertible {
public enum XCodeProjError: Error, CustomStringConvertible, Sendable {
case notFound(path: Path)
case pbxprojNotFound(path: Path)
case xcworkspaceNotFound(path: Path)
Expand Down
8 changes: 6 additions & 2 deletions Sources/XcodeProj/Extensions/Path+Extras.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import PathKit

// MARK: - Path extras.



func systemGlob(_ pattern: UnsafePointer<CChar>!, _ flags: Int32, _ errfunc: (@convention(c) (UnsafePointer<CChar>?, Int32) -> Int32)!, _ vector_ptr: UnsafeMutablePointer<glob_t>!) -> Int32 {
#if os(macOS)
let systemGlob = Darwin.glob
return Darwin.glob(pattern, flags, errfunc, vector_ptr)
#else
let systemGlob = Glibc.glob
return Glibc.glob(pattern, flags, errfunc, vector_ptr)
#endif
}

extension Path {
/// Creates a directory
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeProj/Objects/Files/PBXGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class PBXGroup: PBXFileElement {
// MARK: - Helpers

/// Options passed when adding new groups.
public struct GroupAddingOptions: OptionSet {
public struct GroupAddingOptions: OptionSet, Sendable {
/// Raw value.
public let rawValue: Int

Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Project/WorkspaceSettings.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import PathKit
@preconcurrency import PathKit

public enum WorkspaceSettingsError: Error {
public enum WorkspaceSettingsError: Error, Sendable {
/// thrown when the settings file was not found.
case notFound(path: Path)
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/XcodeProj/Scheme/XCScheme+BuildAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import PathKit
extension XCScheme {
public final class BuildAction: SerialAction {
public final class Entry: Equatable {
public enum BuildFor {
public enum BuildFor: Sendable {
case running, testing, profiling, archiving, analyzing
public static var `default`: [BuildFor] = [.running, .testing, .archiving, .analyzing]
public static var indexing: [BuildFor] = [.testing, .analyzing, .archiving]
public static var testOnly: [BuildFor] = [.testing, .analyzing]
public static let `default`: [BuildFor] = [.running, .testing, .archiving, .analyzing]
public static let indexing: [BuildFor] = [.testing, .analyzing, .archiving]
public static let testOnly: [BuildFor] = [.testing, .analyzing]
}

// MARK: - Attributes
Expand Down
6 changes: 3 additions & 3 deletions Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import PathKit
extension XCScheme {
// swiftlint:disable:next type_body_length
public final class LaunchAction: SerialAction {
public enum Style: String {
public enum Style: String, Sendable {
case auto = "0"
case wait = "1"
case custom = "2"
}

public enum GPUFrameCaptureMode: String {
public enum GPUFrameCaptureMode: String, Sendable {
case autoEnabled = "0"
case metal = "1"
case openGL = "2"
case disabled = "3"
}

public enum GPUValidationMode: String {
public enum GPUValidationMode: String, Sendable {
case enabled = "0"
case disabled = "1"
case extended = "2"
Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Scheme/XCScheme.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import AEXML
import Foundation
import PathKit
@preconcurrency import PathKit

public enum XCSchemeError: Error, CustomStringConvertible {
public enum XCSchemeError: Error, CustomStringConvertible, Sendable {
case notFound(path: Path)
case missing(property: String)

Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Scheme/XCSchemeManagement.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import PathKit
@preconcurrency import PathKit

public enum XCSchemeManagementError: Error, Equatable, LocalizedError, CustomStringConvertible {
public enum XCSchemeManagementError: Error, Equatable, LocalizedError, CustomStringConvertible, Sendable {
/// Thrown when the user tries to initialize a XCSchemeManagement instace passing a path to a file that doesn't exist.
case notFound(path: Path)

Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Utils/CommentedString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct CommentedString {
}

/// Set of characters that are invalid.
private static var invalidCharacters: CharacterSet = {
private static let invalidCharacters: CharacterSet = {
var invalidSet = CharacterSet(charactersIn: "_$")
invalidSet.insert(charactersIn: UnicodeScalar(".") ... UnicodeScalar("9"))
invalidSet.insert(charactersIn: UnicodeScalar("A") ... UnicodeScalar("Z"))
Expand All @@ -29,7 +29,7 @@ struct CommentedString {
}()

/// Set of characters that are invalid.
private static var specialCheckCharacters = CharacterSet(charactersIn: "_/")
private static let specialCheckCharacters = CharacterSet(charactersIn: "_/")

/// Returns a valid string for Xcode projects.
var validString: String {
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeProj/Utils/Decoders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ProjectDecodingContext {

extension CodingUserInfoKey {
/// Context user info key.
static var context: CodingUserInfoKey = CodingUserInfoKey(rawValue: "context")!
static let context: CodingUserInfoKey = CodingUserInfoKey(rawValue: "context")!
}

/// Xcodeproj JSON decoder.
Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Utils/XCConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ final class XCConfigParser {
}

// swiftlint:disable:next force_try
private static var includeRegex = try! NSRegularExpression(pattern: "#include\\s+\"(.+\\.xcconfig)\"", options: .caseInsensitive)
private static let includeRegex = try! NSRegularExpression(pattern: "#include\\s+\"(.+\\.xcconfig)\"", options: .caseInsensitive)
// swiftlint:disable:next force_try
private static var settingRegex = try! NSRegularExpression(pattern: "^([a-zA-Z0-9_\\[\\]=\\*~]+)\\s*=\\s*(\"?.*?\"?)\\s*(?:;\\s*)?(?=$|\\/\\/)", options: [])
private static let settingRegex = try! NSRegularExpression(pattern: "^([a-zA-Z0-9_\\[\\]=\\*~]+)\\s*=\\s*(\"?.*?\"?)\\s*(?:;\\s*)?(?=$|\\/\\/)", options: [])
}

// MARK: - XCConfig Extension (Equatable)
Expand Down

0 comments on commit 19f5029

Please sign in to comment.