From 8a616e132a372bd20ddc79903f88f9183fee4285 Mon Sep 17 00:00:00 2001 From: Pedro Date: Mon, 8 Jul 2024 14:20:44 +0200 Subject: [PATCH 01/13] Update CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74e061fb..e7d2ecce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 8.22.0 + +### Added +* Add `buildArchitectures` to XCScheme+BuildAction by @woin2ee in https://github.com/tuist/XcodeProj/pull/824 + +### Changed +* Update comment to reflect productNameWithExtension() and others by @mikeger in https://github.com/tuist/XcodeProj/pull/823 + ## 8.21.0 ### Fixed From a5120dc37b6b526534c72f215e99147b3cb1cf25 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 20 Jul 2024 20:32:45 +0200 Subject: [PATCH 02/13] docs: add filipracki as a contributor for code (#832) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 631e7f0a..eb0f72ae 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -364,6 +364,15 @@ "contributions": [ "code" ] + }, + { + "login": "filipracki", + "name": "Filip Racki", + "avatar_url": "https://avatars.githubusercontent.com/u/27164368?v=4", + "profile": "https://github.com/filipracki", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 7dd64e12..2f504e86 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Netlify Status](https://api.netlify.com/api/v1/badges/005ef674-d103-4b05-a4d1-79413ce9d766/deploy-status)](https://app.netlify.com/sites/xcodeproj/deploys) -[![All Contributors](https://img.shields.io/badge/all_contributors-40-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-41-orange.svg?style=flat-square)](#contributors-) [![Swift Package Manager](https://img.shields.io/badge/swift%20package%20manager-compatible-brightgreen.svg)](https://swift.org/package-manager/) @@ -192,6 +192,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Артем Ворхлик
Артем Ворхлик

💻 Jaewon-Yun
Jaewon-Yun

💻 Mike Gerasymenko
Mike Gerasymenko

💻 + Filip Racki
Filip Racki

💻 From 5f77765965507c23b5b2361144f5e051316ad6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era=20Buend=C3=ADa?= <663605+pepicrft@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:35:56 +0200 Subject: [PATCH 03/13] Update CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 872148ab..c8d974ca 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1 +1,3 @@ -Check out the organization [CODE OF CONDUCT](https://github.com/tuist/tuist/blob/main/docs/contribution/code-of-conduct.md) +# Code of conduct + +The code of conduct is available in [Tuist's handbook](https://handbook.tuist.io/people/code-of-conduct.html). From b468717a8409b83f90c2b9a4400068c2088fc491 Mon Sep 17 00:00:00 2001 From: Filip Racki Date: Fri, 26 Jul 2024 17:12:52 +0200 Subject: [PATCH 04/13] Add Metal Diagnostics Options to LaunchAction (#828) --- .../Scheme/XCScheme+LaunchAction.swift | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift index c75be731..00724d8a 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift @@ -18,11 +18,13 @@ extension XCScheme { case disabled = "3" } - public enum GPUValidationMode: String, Sendable { - case enabled = "0" - case disabled = "1" - case extended = "2" - } + // The value used to disable 'API Validation'. + // If this feature is not being disabled, this value will not be present. + public let gpuValidationModeDisableValue = "1" + + // The value used to enable 'Shader Validation'. + // If this feature is not being enabled, this value will not be present. + public let gpuShaderValidationModeEnableValue = "2" // MARK: - Static @@ -30,7 +32,6 @@ extension XCScheme { public static let defaultDebugServiceExtension = "internal" private static let defaultLaunchStyle = Style.auto public static let defaultGPUFrameCaptureMode = GPUFrameCaptureMode.autoEnabled - public static let defaultGPUValidationMode = GPUValidationMode.enabled // MARK: - Attributes @@ -50,7 +51,10 @@ extension XCScheme { public var allowLocationSimulation: Bool public var locationScenarioReference: LocationScenarioReference? public var enableGPUFrameCaptureMode: GPUFrameCaptureMode - public var enableGPUValidationMode: GPUValidationMode + public var disableGPUValidationMode: Bool + public var enableGPUShaderValidationMode: Bool + public var showGraphicsOverview: Bool + public var logGraphicsOverview: Bool public var enableAddressSanitizer: Bool public var enableASanStackUseAfterReturn: Bool public var enableThreadSanitizer: Bool @@ -92,7 +96,10 @@ extension XCScheme { allowLocationSimulation: Bool = true, locationScenarioReference: LocationScenarioReference? = nil, enableGPUFrameCaptureMode: GPUFrameCaptureMode = LaunchAction.defaultGPUFrameCaptureMode, - enableGPUValidationMode: GPUValidationMode = LaunchAction.defaultGPUValidationMode, + disableGPUValidationMode: Bool = false, + enableGPUShaderValidationMode: Bool = false, + showGraphicsOverview: Bool = false, + logGraphicsOverview: Bool = false, enableAddressSanitizer: Bool = false, enableASanStackUseAfterReturn: Bool = false, enableThreadSanitizer: Bool = false, @@ -128,7 +135,10 @@ extension XCScheme { self.allowLocationSimulation = allowLocationSimulation self.locationScenarioReference = locationScenarioReference self.enableGPUFrameCaptureMode = enableGPUFrameCaptureMode - self.enableGPUValidationMode = enableGPUValidationMode + self.disableGPUValidationMode = disableGPUValidationMode + self.enableGPUShaderValidationMode = enableGPUShaderValidationMode + self.showGraphicsOverview = showGraphicsOverview + self.logGraphicsOverview = logGraphicsOverview self.enableAddressSanitizer = enableAddressSanitizer self.enableASanStackUseAfterReturn = enableASanStackUseAfterReturn self.enableThreadSanitizer = enableThreadSanitizer @@ -191,8 +201,10 @@ extension XCScheme { enableGPUFrameCaptureMode = element.attributes["enableGPUFrameCaptureMode"] .flatMap { GPUFrameCaptureMode(rawValue: $0) } ?? LaunchAction.defaultGPUFrameCaptureMode - enableGPUValidationMode = element.attributes["enableGPUValidationMode"] - .flatMap { GPUValidationMode(rawValue: $0) } ?? LaunchAction.defaultGPUValidationMode + disableGPUValidationMode = element.attributes["enableGPUValidationMode"] == gpuValidationModeDisableValue + enableGPUShaderValidationMode = element.attributes["enableGPUShaderValidationMode"] == gpuShaderValidationModeEnableValue + showGraphicsOverview = element.attributes["showGraphicsOverview"] == "Yes" + logGraphicsOverview = element.attributes["logGraphicsOverview"] == "Yes" enableAddressSanitizer = element.attributes["enableAddressSanitizer"] == "YES" enableASanStackUseAfterReturn = element.attributes["enableASanStackUseAfterReturn"] == "YES" enableThreadSanitizer = element.attributes["enableThreadSanitizer"] == "YES" @@ -257,8 +269,17 @@ extension XCScheme { if enableGPUFrameCaptureMode != LaunchAction.defaultGPUFrameCaptureMode { attributes["enableGPUFrameCaptureMode"] = enableGPUFrameCaptureMode.rawValue } - if enableGPUValidationMode != LaunchAction.defaultGPUValidationMode { - attributes["enableGPUValidationMode"] = enableGPUValidationMode.rawValue + if disableGPUValidationMode { + attributes["enableGPUValidationMode"] = gpuValidationModeDisableValue + } + if enableGPUShaderValidationMode { + attributes["enableGPUShaderValidationMode"] = gpuShaderValidationModeEnableValue + } + if showGraphicsOverview { + attributes["showGraphicsOverview"] = showGraphicsOverview.xmlString + } + if logGraphicsOverview { + attributes["logGraphicsOverview"] = showGraphicsOverview.xmlString } if enableAddressSanitizer { attributes["enableAddressSanitizer"] = enableAddressSanitizer.xmlString @@ -383,7 +404,10 @@ extension XCScheme { allowLocationSimulation == rhs.allowLocationSimulation && locationScenarioReference == rhs.locationScenarioReference && enableGPUFrameCaptureMode == rhs.enableGPUFrameCaptureMode && - enableGPUValidationMode == rhs.enableGPUValidationMode && + disableGPUValidationMode == rhs.disableGPUValidationMode && + enableGPUShaderValidationMode == rhs.enableGPUShaderValidationMode && + showGraphicsOverview == rhs.showGraphicsOverview && + logGraphicsOverview == rhs.logGraphicsOverview && enableAddressSanitizer == rhs.enableAddressSanitizer && enableASanStackUseAfterReturn == rhs.enableASanStackUseAfterReturn && enableThreadSanitizer == rhs.enableThreadSanitizer && From 951e9397e59dd1cabb369c1e8894643f7be22019 Mon Sep 17 00:00:00 2001 From: Filip Racki Date: Tue, 30 Jul 2024 17:33:58 +0200 Subject: [PATCH 05/13] Fix incorrect way of setting "yes" attributes of "showGraphicsOverview" and "logGraphicsOverview" (#834) --- Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift index 00724d8a..a8770502 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift @@ -276,10 +276,10 @@ extension XCScheme { attributes["enableGPUShaderValidationMode"] = gpuShaderValidationModeEnableValue } if showGraphicsOverview { - attributes["showGraphicsOverview"] = showGraphicsOverview.xmlString + attributes["showGraphicsOverview"] = "Yes" } if logGraphicsOverview { - attributes["logGraphicsOverview"] = showGraphicsOverview.xmlString + attributes["logGraphicsOverview"] = "Yes" } if enableAddressSanitizer { attributes["enableAddressSanitizer"] = enableAddressSanitizer.xmlString From 0a327c67a4158a756dc60d74e01ed8e1699ca53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era=20Buend=C3=ADa?= <663605+pepicrft@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:06:27 +0200 Subject: [PATCH 06/13] chore: set up SwiftLint and SwiftFormat, run them against the project, and run them as part of the CI workflows (#836) * chore: run SwiftLint and SwiftFormat against the project * chore: lint on CI * Fix compilation issue * Lint on macOS because swiftformat can't run on Ubuntu --- .github/workflows/xcodeproj.yml | 15 ++- .gitignore | 4 + .mise.toml | 3 + .mise/tasks/lint | 6 + .mise/tasks/lint-fix | 6 + .swiftformat | 4 +- .../FileSharedAcrossTargetsTests.swift | 4 +- .../AppWithExtensions/AppDelegate.swift | 2 +- Fixtures/iOS/iOS/AppDelegate.swift | 2 +- Package.swift | 4 +- .../Extensions/AEXML+XcodeFormat.swift | 8 +- .../XcodeProj/Extensions/Array+Extras.swift | 4 +- .../XcodeProj/Extensions/Path+Extras.swift | 17 ++- .../XcodeProj/Extensions/String+Utils.swift | 12 +- Sources/XcodeProj/Extensions/String+md5.swift | 32 ++--- .../Objects/BuildPhase/PBXBuildFile.swift | 16 +-- .../Objects/BuildPhase/PBXBuildPhase.swift | 6 +- .../Objects/BuildPhase/PBXBuildRule.swift | 16 +-- .../BuildPhase/PBXCopyFilesBuildPhase.swift | 6 +- .../BuildPhase/PBXShellScriptBuildPhase.swift | 12 +- .../Configuration/XCBuildConfiguration.swift | 4 +- .../Configuration/XCConfigurationList.swift | 14 +- .../Objects/Files/PBXContainerItem.swift | 2 +- .../Objects/Files/PBXContainerItemProxy.swift | 6 +- .../Objects/Files/PBXFileElement.swift | 18 +-- .../Objects/Files/PBXFileReference.swift | 14 +- .../XcodeProj/Objects/Files/PBXGroup.swift | 8 +- .../Objects/Files/XCVersionGroup.swift | 4 +- .../Objects/Project/PBXObjectReference.swift | 8 +- .../Objects/Project/PBXObjects.swift | 6 +- .../Objects/Project/PBXOutputSettings.swift | 12 +- .../XcodeProj/Objects/Project/PBXProj.swift | 4 +- .../Objects/Project/PBXProjEncoder.swift | 22 ++-- .../Objects/Project/PBXProject.swift | 35 ++--- .../Objects/Sourcery/Equality.generated.swift | 14 +- .../XCRemoteSwiftPackageReference.swift | 4 +- .../XCSwiftPackageProductDependency.swift | 2 +- .../Objects/Targets/PBXAggregateTarget.swift | 2 +- .../Objects/Targets/PBXLegacyTarget.swift | 8 +- .../Objects/Targets/PBXNativeTarget.swift | 4 +- .../Objects/Targets/PBXProductType.swift | 2 +- .../Objects/Targets/PBXReferenceProxy.swift | 4 +- .../XcodeProj/Objects/Targets/PBXTarget.swift | 10 +- .../Objects/Targets/PBXTargetDependency.swift | 12 +- .../XcodeProj/Project/WorkspaceSettings.swift | 17 +-- .../XcodeProj/Project/XCBreakpointList.swift | 18 +-- Sources/XcodeProj/Project/XCSharedData.swift | 10 +- Sources/XcodeProj/Project/XCUserData.swift | 12 +- Sources/XcodeProj/Project/Xcode.swift | 18 +-- Sources/XcodeProj/Protocols/Writable.swift | 6 +- .../Scheme/XCScheme+AditionalOption.swift | 4 +- .../Scheme/XCScheme+AnalyzeAction.swift | 4 +- .../Scheme/XCScheme+ArchiveAction.swift | 4 +- .../Scheme/XCScheme+BuildAction.swift | 10 +- .../XCScheme+BuildableProductRunnable.swift | 4 +- .../Scheme/XCScheme+BuildableReference.swift | 8 +- .../XCScheme+CommandLineArguments.swift | 10 +- .../Scheme/XCScheme+EnvironmentVariable.swift | 6 +- .../Scheme/XCScheme+ExecutionAction.swift | 8 +- .../Scheme/XCScheme+LaunchAction.swift | 36 ++--- .../XCScheme+LocationScenarioReference.swift | 4 +- .../Scheme/XCScheme+PathRunnable.swift | 4 +- .../Scheme/XCScheme+ProfileAction.swift | 26 ++-- .../Scheme/XCScheme+RemoteRunnable.swift | 4 +- .../XcodeProj/Scheme/XCScheme+Runnable.swift | 6 +- .../Scheme/XCScheme+SerialAction.swift | 8 +- ...e+StoreKitConfigurationFileReference.swift | 4 +- .../Scheme/XCScheme+TestAction.swift | 32 ++--- .../XcodeProj/Scheme/XCScheme+TestItem.swift | 4 +- .../Scheme/XCScheme+TestPlanReference.swift | 4 +- .../Scheme/XCScheme+TestableReference.swift | 16 +-- Sources/XcodeProj/Scheme/XCScheme.swift | 20 +-- .../XcodeProj/Scheme/XCSchemeManagement.swift | 101 +++++++------- .../Utils/BuildSettingsProvider.swift | 14 +- Sources/XcodeProj/Utils/CommentedString.swift | 2 +- Sources/XcodeProj/Utils/Decoders.swift | 2 +- Sources/XcodeProj/Utils/JSONDecoding.swift | 6 +- Sources/XcodeProj/Utils/PBXBatchUpdater.swift | 124 +++++++++--------- Sources/XcodeProj/Utils/PlistValue.swift | 2 +- .../XcodeProj/Utils/ReferenceGenerator.swift | 36 ++--- Sources/XcodeProj/Utils/XCConfig.swift | 36 ++--- Sources/XcodeProj/Workspace/XCWorkspace.swift | 4 +- .../XcodeProj/Workspace/XCWorkspaceData.swift | 8 +- .../Extensions/AEXML+XcodeFormatTests.swift | 10 +- .../Extensions/XCTestCase+Assertions.swift | 4 +- .../BuildPhase/PBXBuildFileTests.swift | 2 +- .../PBXShellScriptBuildPhaseTests.swift | 8 +- .../XCConfigurationList+Fixtures.swift | 3 +- .../XCConfigurationListTests.swift | 2 +- .../Files/PBXFileReference+Fixtures.swift | 3 +- .../Objects/Files/PBXGroup+Fixtures.swift | 3 +- .../Objects/Files/PBXGroupTests.swift | 2 +- .../Files/XCVersionGroup+Fixtures.swift | 5 +- .../Project/PBXOutputSettingsTests.swift | 32 ++--- .../Objects/Project/PBXProj+Fixtures.swift | 3 +- .../Objects/Project/PBXProjEncoderTests.swift | 52 ++++---- .../Project/PBXProjIntegrationTests.swift | 6 +- .../Objects/Project/PBXProject+Fixtures.swift | 3 +- .../XCLocalSwiftPackageReferenceTests.swift | 2 +- .../Objects/Targets/PBXTarget+Fixtures.swift | 3 +- .../Project/XCBreakpointListTests.swift | 2 +- .../Project/XCUserDataTests.swift | 4 +- .../Project/XcodeProjTests.swift | 4 +- .../XCScheme+BuildableReferenceTests.swift | 2 +- .../Scheme/XCSchemeManagementTests.swift | 16 +-- .../XcodeProjTests/Scheme/XCSchemeTests.swift | 12 +- Tests/XcodeProjTests/Tests/Fixtures.swift | 1 - Tests/XcodeProjTests/Tests/testWrite.swift | 23 ++-- .../Utils/ReferenceGeneratorTests.swift | 2 +- .../XcodeProjTests/Utils/XCConfigTests.swift | 6 +- 110 files changed, 642 insertions(+), 613 deletions(-) create mode 100644 .mise.toml create mode 100755 .mise/tasks/lint create mode 100755 .mise/tasks/lint-fix diff --git a/.github/workflows/xcodeproj.yml b/.github/workflows/xcodeproj.yml index 0ad6989d..7d921922 100644 --- a/.github/workflows/xcodeproj.yml +++ b/.github/workflows/xcodeproj.yml @@ -7,6 +7,9 @@ concurrency: group: xcodeproj-${{ github.head_ref }} cancel-in-progress: true +env: + MISE_EXPERIMENTAL: 1 + jobs: build: name: Build (macOS) @@ -49,12 +52,10 @@ jobs: git config --global init.defaultBranch main - name: Build and run tests run: swift test --enable-test-discovery - swiftlint: - name: Swiftlint - runs-on: ubuntu-latest + lint: + name: Lint + runs-on: macos-latest steps: - uses: actions/checkout@v3 - - name: GitHub Action for SwiftLint - uses: norio-nomura/action-swiftlint@3.2.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: jdx/mise-action@v2 + - run: mise run lint diff --git a/.gitignore b/.gitignore index 0dac9e3e..97f05bc9 100644 --- a/.gitignore +++ b/.gitignore @@ -186,3 +186,7 @@ tmp/ XcodeProj.framework.zip !Fixtures/**/xcuserdata/ + +Derived/ +*.xcworkspace/ +*.xcodeproj/ diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 00000000..317af7dd --- /dev/null +++ b/.mise.toml @@ -0,0 +1,3 @@ +[tools] +swiftlint = "0.54.0" +swiftformat = "0.54.3" diff --git a/.mise/tasks/lint b/.mise/tasks/lint new file mode 100755 index 00000000..d1a523f1 --- /dev/null +++ b/.mise/tasks/lint @@ -0,0 +1,6 @@ +#!/bin/bash +# mise description="Lint the workspace" +set -euo pipefail + +swiftformat $MISE_PROJECT_ROOT --lint +swiftlint lint --quiet --config $MISE_PROJECT_ROOT/.swiftlint.yml $MISE_PROJECT_ROOT/Sources diff --git a/.mise/tasks/lint-fix b/.mise/tasks/lint-fix new file mode 100755 index 00000000..cfc03595 --- /dev/null +++ b/.mise/tasks/lint-fix @@ -0,0 +1,6 @@ +#!/bin/bash +# mise description="Lint the workspace fixing issues" +set -euo pipefail + +swiftformat $MISE_PROJECT_ROOT +swiftlint lint --fix --quiet --config $MISE_PROJECT_ROOT/.swiftlint.yml $MISE_PROJECT_ROOT/Sources diff --git a/.swiftformat b/.swiftformat index cce74ebe..d9bc86be 100644 --- a/.swiftformat +++ b/.swiftformat @@ -5,6 +5,8 @@ # format options +--disable wrapMultilineStatementBraces +--disable braces --allman false --binarygrouping 4,8 --commas always @@ -32,4 +34,4 @@ --stripunusedargs always --trimwhitespace always --wraparguments preserve ---wrapcollections preserve \ No newline at end of file +--wrapcollections preserve diff --git a/Fixtures/FileSharedAcrossTargets/FileSharedAcrossTargetsTests/FileSharedAcrossTargetsTests.swift b/Fixtures/FileSharedAcrossTargets/FileSharedAcrossTargetsTests/FileSharedAcrossTargetsTests.swift index 62976e86..5b957f98 100644 --- a/Fixtures/FileSharedAcrossTargets/FileSharedAcrossTargetsTests/FileSharedAcrossTargetsTests.swift +++ b/Fixtures/FileSharedAcrossTargets/FileSharedAcrossTargetsTests/FileSharedAcrossTargetsTests.swift @@ -2,7 +2,6 @@ import XCTest @testable import FileSharedAcrossTargets final class FileSharedAcrossTargetsTests: XCTestCase { - override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. } @@ -21,9 +20,8 @@ final class FileSharedAcrossTargetsTests: XCTestCase { func testPerformanceExample() throws { // This is an example of a performance test case. - self.measure { + measure { // Put the code you want to measure the time of here. } } - } diff --git a/Fixtures/iOS/AppWithExtensions/AppWithExtensions/AppDelegate.swift b/Fixtures/iOS/AppWithExtensions/AppWithExtensions/AppDelegate.swift index ec501c43..5d0695c4 100644 --- a/Fixtures/iOS/AppWithExtensions/AppWithExtensions/AppDelegate.swift +++ b/Fixtures/iOS/AppWithExtensions/AppWithExtensions/AppDelegate.swift @@ -1,6 +1,6 @@ import UIKit -@UIApplicationMain +@main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. diff --git a/Fixtures/iOS/iOS/AppDelegate.swift b/Fixtures/iOS/iOS/AppDelegate.swift index 843ae1f6..22f27cb4 100644 --- a/Fixtures/iOS/iOS/AppDelegate.swift +++ b/Fixtures/iOS/iOS/AppDelegate.swift @@ -8,7 +8,7 @@ import UIKit -@UIApplicationMain +@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? diff --git a/Package.swift b/Package.swift index dcd5cc92..4e4b6683 100644 --- a/Package.swift +++ b/Package.swift @@ -10,7 +10,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/tadija/AEXML.git", .upToNextMinor(from: "4.6.1")), .package(url: "https://github.com/kylef/PathKit.git", .upToNextMinor(from: "1.0.1")), - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0") + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0"), ], targets: [ .target(name: "XcodeProj", @@ -19,7 +19,7 @@ let package = Package( .product(name: "AEXML", package: "AEXML"), ], swiftSettings: [ - .enableExperimentalFeature("StrictConcurrency") + .enableExperimentalFeature("StrictConcurrency"), ]), .testTarget(name: "XcodeProjTests", dependencies: ["XcodeProj"]), ] diff --git a/Sources/XcodeProj/Extensions/AEXML+XcodeFormat.swift b/Sources/XcodeProj/Extensions/AEXML+XcodeFormat.swift index d8c4ec15..81017033 100644 --- a/Sources/XcodeProj/Extensions/AEXML+XcodeFormat.swift +++ b/Sources/XcodeProj/Extensions/AEXML+XcodeFormat.swift @@ -103,13 +103,13 @@ let attributesOrder: [String: [String]] = [ "RemoteRunnable": [ "runnableDebuggingMode", "BundleIdentifier", - "RemotePath" + "RemotePath", ], "Scheme": [ "LastUpgradeVersion", "wasCreatedForAppExtension", - "version" - ] + "version", + ], ] extension AEXMLElement { @@ -128,7 +128,7 @@ extension AEXMLElement { if !attributes.isEmpty { // insert known attributes in the specified order. - var attributes = self.attributes + var attributes = attributes for key in attributesOrder[name] ?? [] { if let value = attributes.removeValue(forKey: key) { print(key: key, value: value) diff --git a/Sources/XcodeProj/Extensions/Array+Extras.swift b/Sources/XcodeProj/Extensions/Array+Extras.swift index 310fc3e9..851c0055 100644 --- a/Sources/XcodeProj/Extensions/Array+Extras.swift +++ b/Sources/XcodeProj/Extensions/Array+Extras.swift @@ -1,13 +1,13 @@ import Foundation -extension Array where Element: Hashable { +public extension Array where Element: Hashable { /// Return the array with all duplicates removed. /// /// i.e. `[ 1, 2, 3, 1, 2 ].uniqued() == [ 1, 2, 3 ]` /// /// - note: Taken from stackoverflow.com/a/46354989/3141234, as /// per @Alexander's comment. - public func uniqued() -> [Element] { + func uniqued() -> [Element] { var seen = Set() return filter { seen.insert($0).inserted } } diff --git a/Sources/XcodeProj/Extensions/Path+Extras.swift b/Sources/XcodeProj/Extensions/Path+Extras.swift index 5279f9d0..75d0f154 100644 --- a/Sources/XcodeProj/Extensions/Path+Extras.swift +++ b/Sources/XcodeProj/Extensions/Path+Extras.swift @@ -1,17 +1,16 @@ import Foundation + // swiftlint:disable all import PathKit // MARK: - Path extras. - - func systemGlob(_ pattern: UnsafePointer!, _ flags: Int32, _ errfunc: (@convention(c) (UnsafePointer?, Int32) -> Int32)!, _ vector_ptr: UnsafeMutablePointer!) -> Int32 { -#if os(macOS) - return Darwin.glob(pattern, flags, errfunc, vector_ptr) -#else - return Glibc.glob(pattern, flags, errfunc, vector_ptr) -#endif + #if os(macOS) + return Darwin.glob(pattern, flags, errfunc, vector_ptr) + #else + return Glibc.glob(pattern, flags, errfunc, vector_ptr) + #endif } extension Path { @@ -39,9 +38,9 @@ extension Path { let flags = GLOB_TILDE | GLOB_BRACE | GLOB_MARK if systemGlob(cPattern, flags, nil, >) == 0 { #if os(macOS) - let matchc = gt.gl_matchc + let matchc = gt.gl_matchc #else - let matchc = gt.gl_pathc + let matchc = gt.gl_pathc #endif return (0 ..< Int(matchc)).compactMap { index in if let path = String(validatingUTF8: gt.gl_pathv[index]!) { diff --git a/Sources/XcodeProj/Extensions/String+Utils.swift b/Sources/XcodeProj/Extensions/String+Utils.swift index a9ac1a05..51fc0bf3 100644 --- a/Sources/XcodeProj/Extensions/String+Utils.swift +++ b/Sources/XcodeProj/Extensions/String+Utils.swift @@ -4,22 +4,22 @@ import Foundation import SwiftGlibc public func arc4random_uniform(_ max: UInt32) -> Int32 { - (SwiftGlibc.rand() % Int32(max - 1)) + SwiftGlibc.rand() % Int32(max - 1) } #endif -extension String { - public var quoted: String { +public extension String { + var quoted: String { "\"\(self)\"" } - public var isQuoted: Bool { + var isQuoted: Bool { hasPrefix("\"") && hasSuffix("\"") } - public static func random(length: Int = 20) -> String { + static func random(length: Int = 20) -> String { let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - var randomString: String = "" + var randomString = "" for _ in 0 ..< length { let randomValue = arc4random_uniform(UInt32(base.count)) diff --git a/Sources/XcodeProj/Extensions/String+md5.swift b/Sources/XcodeProj/Extensions/String+md5.swift index 8ffa9d1f..1c0afa87 100644 --- a/Sources/XcodeProj/Extensions/String+md5.swift +++ b/Sources/XcodeProj/Extensions/String+md5.swift @@ -1,6 +1,6 @@ // swiftlint:disable all // -// String+MD5.swift +// String+md5.swift // Kingfisher // // To date, adding CommonCrypto to a Swift framework is problematic. See: @@ -22,7 +22,7 @@ import Foundation #if canImport(CryptoKit) -import CryptoKit + import CryptoKit #endif extension String { @@ -31,14 +31,14 @@ extension String { return self } #if canImport(CryptoKit) - if #available(OSX 10.15, *) { - return Insecure.MD5.hash(data: data) - .withUnsafeBytes { Array($0) }.hexString - } else { - return data.slowMD5 - } + if #available(OSX 10.15, *) { + return Insecure.MD5.hash(data: data) + .withUnsafeBytes { Array($0) }.hexString + } else { + return data.slowMD5 + } #else - return data.slowMD5 + return data.slowMD5 #endif } } @@ -48,11 +48,11 @@ private let char0 = UInt8(UnicodeScalar("0").value) private extension DataProtocol { var hexString: String { - let hexLen = self.count * 2 + let hexLen = count * 2 var hexChars = [UInt8](repeating: 0, count: hexLen) var offset = 0 - self.regions.forEach { (_) in + for _ in regions { for i in self { hexChars[Int(offset * 2)] = itoh((i >> 4) & 0xF) hexChars[Int(offset * 2 + 1)] = itoh(i & 0xF) @@ -64,7 +64,7 @@ private extension DataProtocol { } func itoh(_ value: UInt8) -> UInt8 { - return (value > 9) ? (charA + value - 10) : (char0 + value) + (value > 9) ? (charA + value - 10) : (char0 + value) } } @@ -91,7 +91,7 @@ func arrayOfBytes(_ value: T, length: Int? = nil) -> [UInt8] { let valuePointer = UnsafeMutablePointer.allocate(capacity: 1) valuePointer.pointee = value - let bytes = valuePointer.withMemoryRebound(to: UInt8.self, capacity: totalBytes) { (bytesPointer) -> [UInt8] in + let bytes = valuePointer.withMemoryRebound(to: UInt8.self, capacity: totalBytes) { bytesPointer -> [UInt8] in var bytes = [UInt8](repeating: 0, count: totalBytes) for j in 0 ..< min(MemoryLayout.size, totalBytes) { bytes[totalBytes - 1 - j] = (bytesPointer + j).pointee @@ -282,7 +282,7 @@ class MD5: HashProtocol { F = B ^ C ^ D g = (3 * j + 5) % 16 case 48 ... 63: - F = C ^ (B | (~D)) + F = C ^ (B | ~D) g = (7 * j) % 16 default: break @@ -303,8 +303,8 @@ class MD5: HashProtocol { var result = [UInt8]() result.reserveCapacity(hh.count / 4) - hh.forEach { - let itemLE = $0.littleEndian + for item in hh { + let itemLE = item.littleEndian let r1 = UInt8(itemLE & 0xFF) let r2 = UInt8((itemLE >> 8) & 0xFF) let r3 = UInt8((itemLE >> 16) & 0xFF) diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift index 99e8c844..5bf89bc2 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift @@ -114,28 +114,28 @@ extension PBXBuildFile { /// - Returns: build phase type. /// - Throws: an error if this method is called before the build file is added to any project. func getBuildPhase() throws -> PBXBuildPhase? { - if let buildPhase = buildPhase { + if let buildPhase { return buildPhase } let projectObjects = try objects() if let buildPhase = projectObjects.sourcesBuildPhases.values - .first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } else if let buildPhase = projectObjects.frameworksBuildPhases - .values.first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .values.first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } else if let buildPhase = projectObjects .resourcesBuildPhases.values - .first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } else if let buildPhase = projectObjects.copyFilesBuildPhases - .values.first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .values.first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } else if let buildPhase = projectObjects.headersBuildPhases - .values.first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .values.first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } else if let buildPhase = projectObjects.carbonResourcesBuildPhases - .values.first(where: { $0.fileReferences?.map { $0.value }.contains(reference.value) == true }) { + .values.first(where: { $0.fileReferences?.map(\.value).contains(reference.value) == true }) { return buildPhase } return nil @@ -186,7 +186,7 @@ final class PBXBuildPhaseFile: PlistSerializable, Equatable { if let platformFilters = buildFile.platformFilters { dictionary["platformFilters"] = .array(platformFilters.map { .string(.init($0)) }) } - let comment = try buildPhase.name().flatMap { "\(try buildFile.fileName() ?? "(null)") in \($0)" } + let comment = try buildPhase.name().flatMap { try "\(buildFile.fileName() ?? "(null)") in \($0)" } return (key: CommentedString(reference, comment: comment), value: .dictionary(dictionary)) } diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift index b6f261a1..953be5c8 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift @@ -86,7 +86,7 @@ public class PBXBuildPhase: PBXContainerItem { override func plistValues(proj: PBXProj, reference: String) throws -> [CommentedString: PlistValue] { var dictionary = try super.plistValues(proj: proj, reference: reference) dictionary["buildActionMask"] = .string(CommentedString("\(buildActionMask)")) - if let fileReferences = fileReferences { + if let fileReferences { let files: PlistValue = .array(fileReferences.map { fileReference in let buildFile: PBXBuildFile? = fileReference.getObject() let name = buildFile.flatMap { try? $0.fileName() } ?? nil @@ -97,10 +97,10 @@ public class PBXBuildPhase: PBXContainerItem { }) dictionary["files"] = files } - if let inputFileListPaths = inputFileListPaths { + if let inputFileListPaths { dictionary["inputFileListPaths"] = .array(inputFileListPaths.map { .string(CommentedString($0)) }) } - if let outputFileListPaths = outputFileListPaths { + if let outputFileListPaths { dictionary["outputFileListPaths"] = .array(outputFileListPaths.map { .string(CommentedString($0)) }) } dictionary["runOnlyForDeploymentPostprocessing"] = .string(CommentedString("\(runOnlyForDeploymentPostprocessing.int)")) diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildRule.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildRule.swift index 592cded4..45b49807 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildRule.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildRule.swift @@ -18,7 +18,7 @@ public final class PBXBuildRule: PBXObject { /// Element name. public var name: String? - + /// The discovered dependency file to use public var dependencyFile: String? @@ -111,28 +111,28 @@ extension PBXBuildRule: PlistSerializable { var dictionary: [CommentedString: PlistValue] = [:] dictionary["isa"] = .string(CommentedString(PBXBuildRule.isa)) dictionary["compilerSpec"] = .string(CommentedString(compilerSpec)) - if let dependencyFile = dependencyFile { + if let dependencyFile { dictionary["dependencyFile"] = .string(CommentedString(dependencyFile)) } - if let filePatterns = filePatterns { + if let filePatterns { dictionary["filePatterns"] = .string(CommentedString(filePatterns)) } dictionary["fileType"] = .string(CommentedString(fileType)) dictionary["isEditable"] = .string(CommentedString("\(isEditable.int)")) - if let name = name { + if let name { dictionary["name"] = .string(CommentedString(name)) } dictionary["outputFiles"] = .array(outputFiles.map { .string(CommentedString($0)) }) - if let inputFiles = inputFiles { + if let inputFiles { dictionary["inputFiles"] = .array(inputFiles.map { .string(CommentedString($0)) }) } - if let outputFilesCompilerFlags = outputFilesCompilerFlags { + if let outputFilesCompilerFlags { dictionary["outputFilesCompilerFlags"] = .array(outputFilesCompilerFlags.map { PlistValue.string(CommentedString($0)) }) } - if let script = script { + if let script { dictionary["script"] = .string(CommentedString(script)) } - if let runOncePerArchitecture = runOncePerArchitecture { + if let runOncePerArchitecture { dictionary["runOncePerArchitecture"] = .string(CommentedString("\(runOncePerArchitecture.int)")) } return (key: CommentedString(reference, comment: PBXBuildRule.isa), diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXCopyFilesBuildPhase.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXCopyFilesBuildPhase.swift index 2c30cc9a..0fa51e1c 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXCopyFilesBuildPhase.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXCopyFilesBuildPhase.swift @@ -84,13 +84,13 @@ extension PBXCopyFilesBuildPhase: PlistSerializable { func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = try plistValues(proj: proj, reference: reference) dictionary["isa"] = .string(CommentedString(PBXCopyFilesBuildPhase.isa)) - if let dstPath = dstPath { + if let dstPath { dictionary["dstPath"] = .string(CommentedString(dstPath)) } - if let name = name { + if let name { dictionary["name"] = .string(CommentedString(name)) } - if let dstSubfolderSpec = dstSubfolderSpec { + if let dstSubfolderSpec { dictionary["dstSubfolderSpec"] = .string(CommentedString("\(dstSubfolderSpec.rawValue)")) } return (key: CommentedString(reference, comment: name ?? "CopyFiles"), value: .dictionary(dictionary)) diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXShellScriptBuildPhase.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXShellScriptBuildPhase.swift index 6cfc30fc..4790dc45 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXShellScriptBuildPhase.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXShellScriptBuildPhase.swift @@ -91,8 +91,8 @@ public final class PBXShellScriptBuildPhase: PBXBuildPhase { public required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) name = try container.decodeIfPresent(.name) - inputPaths = (try container.decodeIfPresent(.inputPaths)) ?? [] - outputPaths = (try container.decodeIfPresent(.outputPaths)) ?? [] + inputPaths = try (container.decodeIfPresent(.inputPaths)) ?? [] + outputPaths = try (container.decodeIfPresent(.outputPaths)) ?? [] shellPath = try container.decodeIfPresent(.shellPath) shellScript = try container.decodeIfPresent(.shellScript) showEnvVarsInLog = try container.decodeIntBoolIfPresent(.showEnvVarsInLog) ?? true @@ -113,18 +113,18 @@ extension PBXShellScriptBuildPhase: PlistSerializable { func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = try plistValues(proj: proj, reference: reference) dictionary["isa"] = .string(CommentedString(PBXShellScriptBuildPhase.isa)) - if let shellPath = shellPath { + if let shellPath { dictionary["shellPath"] = .string(CommentedString(shellPath)) } dictionary["inputPaths"] = .array(inputPaths.map { .string(CommentedString($0)) }) - if let name = name { + if let name { dictionary["name"] = .string(CommentedString(name)) } dictionary["outputPaths"] = .array(outputPaths.map { .string(CommentedString($0)) }) - if let shellScript = shellScript { + if let shellScript { dictionary["shellScript"] = .string(CommentedString(shellScript)) } - if let dependencyFile = dependencyFile { + if let dependencyFile { dictionary["dependencyFile"] = .string(CommentedString(dependencyFile)) } if !showEnvVarsInLog { diff --git a/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift b/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift index 468984cc..71e05c3d 100644 --- a/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift +++ b/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift @@ -13,7 +13,7 @@ public final class XCBuildConfiguration: PBXObject { baseConfigurationReference?.getObject() } set { - if let newValue = newValue { + if let newValue { baseConfigurationReference = newValue.reference } } @@ -104,7 +104,7 @@ extension XCBuildConfiguration: PlistSerializable { dictionary["isa"] = .string(CommentedString(XCBuildConfiguration.isa)) dictionary["name"] = .string(CommentedString(name)) dictionary["buildSettings"] = buildSettings.plist() - if let baseConfigurationReference = baseConfigurationReference { + if let baseConfigurationReference { let fileElement: PBXFileElement? = baseConfigurationReference.getObject() dictionary["baseConfigurationReference"] = .string(CommentedString(baseConfigurationReference.value, comment: fileElement?.fileName())) } diff --git a/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift b/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift index 0bf2cfe3..8cf06af8 100644 --- a/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift +++ b/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift @@ -68,19 +68,19 @@ public final class XCConfigurationList: PBXObject { // MARK: - Helpers -extension XCConfigurationList { +public extension XCConfigurationList { /// Returns the build configuration with the given name (if it exists) /// /// - Parameter name: configuration name. /// - Returns: build configuration if it exists. - public func configuration(name: String) -> XCBuildConfiguration? { + func configuration(name: String) -> XCBuildConfiguration? { buildConfigurations.first(where: { $0.name == name }) } /// Adds the default configurations, debug and release /// /// - Returns: the created configurations. - public func addDefaultConfigurations() throws -> [XCBuildConfiguration] { + func addDefaultConfigurations() throws -> [XCBuildConfiguration] { var configurations: [XCBuildConfiguration] = [] let debug = XCBuildConfiguration(name: "Debug") @@ -99,7 +99,7 @@ extension XCConfigurationList { /// /// - Parameter reference: configuration list reference. /// - Returns: target or project with the given configuration list. - public func objectWithConfigurationList() throws -> PBXObject? { + func objectWithConfigurationList() throws -> PBXObject? { let projectObjects = try objects() return projectObjects.projects.first(where: { $0.value.buildConfigurationListReference == reference })?.value ?? projectObjects.nativeTargets.first(where: { $0.value.buildConfigurationListReference == reference })?.value ?? @@ -120,11 +120,11 @@ extension XCConfigurationList: PlistSerializable { return .string(CommentedString(configReference.value, comment: config?.name)) }) dictionary["defaultConfigurationIsVisible"] = .string(CommentedString("\(defaultConfigurationIsVisible.int)")) - if let defaultConfigurationName = defaultConfigurationName { + if let defaultConfigurationName { dictionary["defaultConfigurationName"] = .string(CommentedString(defaultConfigurationName)) } - return (key: CommentedString(reference, comment: try plistComment()), - value: .dictionary(dictionary)) + return try (key: CommentedString(reference, comment: plistComment()), + value: .dictionary(dictionary)) } private func plistComment() throws -> String? { diff --git a/Sources/XcodeProj/Objects/Files/PBXContainerItem.swift b/Sources/XcodeProj/Objects/Files/PBXContainerItem.swift index 2e11f903..dfc68661 100644 --- a/Sources/XcodeProj/Objects/Files/PBXContainerItem.swift +++ b/Sources/XcodeProj/Objects/Files/PBXContainerItem.swift @@ -26,7 +26,7 @@ public class PBXContainerItem: PBXObject { func plistValues(proj _: PBXProj, reference _: String) throws -> [CommentedString: PlistValue] { var dictionary = [CommentedString: PlistValue]() - if let comments = comments { + if let comments { dictionary["comments"] = .string(CommentedString(comments)) } return dictionary diff --git a/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift b/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift index f244aead..014bc3ee 100644 --- a/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift +++ b/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift @@ -156,13 +156,13 @@ extension PBXContainerItemProxy: PlistSerializable { var dictionary: [CommentedString: PlistValue] = [:] dictionary["isa"] = .string(CommentedString(PBXContainerItemProxy.isa)) dictionary["containerPortal"] = .string(CommentedString(containerPortalReference.value, comment: containerPortal.comment)) - if let proxyType = proxyType { + if let proxyType { dictionary["proxyType"] = .string(CommentedString("\(proxyType.rawValue)")) } - if let remoteGlobalID = remoteGlobalID { + if let remoteGlobalID { dictionary["remoteGlobalIDString"] = .string(CommentedString(remoteGlobalID.uuid)) } - if let remoteInfo = remoteInfo { + if let remoteInfo { dictionary["remoteInfo"] = .string(CommentedString(remoteInfo)) } return (key: CommentedString(reference, diff --git a/Sources/XcodeProj/Objects/Files/PBXFileElement.swift b/Sources/XcodeProj/Objects/Files/PBXFileElement.swift index 573e8ee8..5f3e80dc 100644 --- a/Sources/XcodeProj/Objects/Files/PBXFileElement.swift +++ b/Sources/XcodeProj/Objects/Files/PBXFileElement.swift @@ -98,29 +98,29 @@ public class PBXFileElement: PBXContainerItem, PlistSerializable { func plistKeyAndValue(proj _: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = [:] dictionary["isa"] = .string(CommentedString(PBXFileElement.isa)) - if let name = name { + if let name { dictionary["name"] = .string(CommentedString(name)) } - if let path = path { + if let path { dictionary["path"] = .string(CommentedString(path)) } - if let sourceTree = sourceTree { + if let sourceTree { dictionary["sourceTree"] = sourceTree.plist() } - if let includeInIndex = includeInIndex { + if let includeInIndex { dictionary["includeInIndex"] = .string(CommentedString("\(includeInIndex.int)")) } - if let usesTabs = usesTabs { + if let usesTabs { dictionary["usesTabs"] = .string(CommentedString("\(usesTabs.int)")) } - if let indentWidth = indentWidth { + if let indentWidth { dictionary["indentWidth"] = .string(CommentedString("\(indentWidth)")) } - if let tabWidth = tabWidth { + if let tabWidth { dictionary["tabWidth"] = .string(CommentedString("\(tabWidth)")) } - if let wrapsLines = wrapsLines { + if let wrapsLines { dictionary["wrapsLines"] = .string(CommentedString("\(wrapsLines.int)")) } return (key: CommentedString(reference, @@ -173,7 +173,7 @@ public extension PBXFileElement { let projectObjects = try objects() let isThisElementRoot = projectObjects.projects.values.first(where: { $0.mainGroup == self }) != nil if isThisElementRoot { - if let path = path { + if let path { return sourceRoot + Path(path) } return sourceRoot diff --git a/Sources/XcodeProj/Objects/Files/PBXFileReference.swift b/Sources/XcodeProj/Objects/Files/PBXFileReference.swift index a1a0ff35..9595e253 100644 --- a/Sources/XcodeProj/Objects/Files/PBXFileReference.swift +++ b/Sources/XcodeProj/Objects/Files/PBXFileReference.swift @@ -110,25 +110,25 @@ public final class PBXFileReference: PBXFileElement { override func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:] dictionary["isa"] = .string(CommentedString(PBXFileReference.isa)) - if let lastKnownFileType = lastKnownFileType { + if let lastKnownFileType { dictionary["lastKnownFileType"] = .string(CommentedString(lastKnownFileType)) } - if let fileEncoding = fileEncoding { + if let fileEncoding { dictionary["fileEncoding"] = .string(CommentedString("\(fileEncoding)")) } - if let explicitFileType = self.explicitFileType { + if let explicitFileType { dictionary["explicitFileType"] = .string(CommentedString(explicitFileType)) } - if let lineEnding = lineEnding { + if let lineEnding { dictionary["lineEnding"] = .string(CommentedString("\(lineEnding)")) } - if let languageSpecificationIdentifier = languageSpecificationIdentifier { + if let languageSpecificationIdentifier { dictionary["languageSpecificationIdentifier"] = .string(CommentedString(languageSpecificationIdentifier)) } - if let xcLanguageSpecificationIdentifier = xcLanguageSpecificationIdentifier { + if let xcLanguageSpecificationIdentifier { dictionary["xcLanguageSpecificationIdentifier"] = .string(CommentedString(xcLanguageSpecificationIdentifier)) } - if let plistStructureDefinitionIdentifier = plistStructureDefinitionIdentifier { + if let plistStructureDefinitionIdentifier { dictionary["plistStructureDefinitionIdentifier"] = .string(CommentedString(plistStructureDefinitionIdentifier)) } return (key: CommentedString(reference, comment: name ?? path), diff --git a/Sources/XcodeProj/Objects/Files/PBXGroup.swift b/Sources/XcodeProj/Objects/Files/PBXGroup.swift index 34add940..05cece65 100644 --- a/Sources/XcodeProj/Objects/Files/PBXGroup.swift +++ b/Sources/XcodeProj/Objects/Files/PBXGroup.swift @@ -61,7 +61,7 @@ public class PBXGroup: PBXFileElement { let objects = decoder.context.objects let objectReferenceRepository = decoder.context.objectReferenceRepository let container = try decoder.container(keyedBy: CodingKeys.self) - let childrenReferences: [String] = (try container.decodeIfPresent(.children)) ?? [] + let childrenReferences: [String] = try (container.decodeIfPresent(.children)) ?? [] self.childrenReferences = childrenReferences.map { objectReferenceRepository.getOrCreate(reference: $0, objects: objects) } try super.init(from: decoder) } @@ -71,7 +71,7 @@ public class PBXGroup: PBXFileElement { override func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:] dictionary["isa"] = .string(CommentedString(type(of: self).isa)) - dictionary["children"] = .array(childrenReferences.map { (fileReference) -> PlistValue in + dictionary["children"] = .array(childrenReferences.map { fileReference -> PlistValue in let fileElement: PBXFileElement? = fileReference.getObject() return .string(CommentedString(fileReference.value, comment: fileElement?.fileName())) }) @@ -134,7 +134,7 @@ public extension PBXGroup { /// - Returns: created groups. @discardableResult func addGroup(named groupName: String, options: GroupAddingOptions = []) throws -> [PBXGroup] { - let objects = try self.objects() + let objects = try objects() return groupName.components(separatedBy: "/").reduce(into: [PBXGroup]()) { groups, name in let group = groups.last ?? self let newGroup = PBXGroup(children: [], sourceTree: .group, name: name, path: options.contains(.withoutFolder) ? nil : name) @@ -152,7 +152,7 @@ public extension PBXGroup { /// - Returns: created groups. @discardableResult func addVariantGroup(named groupName: String) throws -> [PBXVariantGroup] { - let objects = try self.objects() + let objects = try objects() return groupName.components(separatedBy: "/").reduce(into: [PBXVariantGroup]()) { groups, name in let group = groups.last ?? self diff --git a/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift b/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift index 3087294f..d548a01e 100644 --- a/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift +++ b/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift @@ -87,10 +87,10 @@ public final class XCVersionGroup: PBXGroup { override func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:] dictionary["isa"] = .string(CommentedString(XCVersionGroup.isa)) - if let versionGroupType = versionGroupType { + if let versionGroupType { dictionary["versionGroupType"] = .string(CommentedString(versionGroupType)) } - if let currentVersionReference = currentVersionReference { + if let currentVersionReference { let fileElement: PBXFileElement? = currentVersionReference.getObject() dictionary["currentVersion"] = .string(CommentedString(currentVersionReference.value, comment: fileElement?.fileName())) } diff --git a/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift b/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift index c72a943a..3f544af2 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift @@ -54,7 +54,7 @@ class PBXObjectReference: NSObject, Comparable, NSCopying { let object = objects?.delete(reference: self) self.value = value temporary = false - if let object = object { + if let object { objects?.add(object: object) } } @@ -64,7 +64,7 @@ class PBXObjectReference: NSObject, Comparable, NSCopying { let object = objects?.delete(reference: self) value = "TEMP_\(UUID().uuidString)" temporary = true - if let object = object { + if let object { objects?.add(object: object) } } @@ -130,7 +130,7 @@ class PBXObjectReference: NSObject, Comparable, NSCopying { if let object = object as? T { return object } - guard let objects = objects else { + guard let objects else { throw PBXObjectError.objectsReleased } guard let object = objects.get(reference: self) as? T else { @@ -143,7 +143,7 @@ class PBXObjectReference: NSObject, Comparable, NSCopying { extension Array where Element: PBXObject { func references() -> [PBXObjectReference] { - map { $0.reference } + map(\.reference) } } diff --git a/Sources/XcodeProj/Objects/Project/PBXObjects.swift b/Sources/XcodeProj/Objects/Project/PBXObjects.swift index 5f8a568f..5fbf74e1 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjects.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjects.swift @@ -142,8 +142,8 @@ class PBXObjects: Equatable { /// - Parameters: /// - objects: project objects init(objects: [PBXObject] = []) { - objects.forEach { - self.add(object: $0) + for item in objects { + add(object: item) } } @@ -194,7 +194,6 @@ class PBXObjects: Equatable { // subclasses of PBXGroup; must be tested before PBXGroup case let object as PBXVariantGroup: _variantGroups[objectReference] = object case let object as XCVersionGroup: _versionGroups[objectReference] = object - // everything else case let object as PBXBuildFile: _buildFiles[objectReference] = object case let object as PBXAggregateTarget: _aggregateTargets[objectReference] = object @@ -219,7 +218,6 @@ class PBXObjects: Equatable { case let object as XCRemoteSwiftPackageReference: _remoteSwiftPackageReferences[objectReference] = object case let object as XCLocalSwiftPackageReference: _localSwiftPackageReferences[objectReference] = object case let object as XCSwiftPackageProductDependency: _swiftPackageProductDependencies[objectReference] = object - default: fatalError("Unhandled PBXObject type for \(object), this is likely a bug / todo") } } diff --git a/Sources/XcodeProj/Objects/Project/PBXOutputSettings.swift b/Sources/XcodeProj/Objects/Project/PBXOutputSettings.swift index 77bf7b7e..0d82fb22 100644 --- a/Sources/XcodeProj/Objects/Project/PBXOutputSettings.swift +++ b/Sources/XcodeProj/Objects/Project/PBXOutputSettings.swift @@ -39,12 +39,12 @@ public enum PBXFileOrder { /// Sort files by their file name. This is a case sensistive sort with lower case names coming after uppercase names. case byFilename - internal func sort(lhs: (PBXObjectReference, Object), rhs: (PBXObjectReference, Object)) -> Bool + func sort(lhs: (PBXObjectReference, Object), rhs: (PBXObjectReference, Object)) -> Bool where Object: PlistSerializable & Equatable { lhs.0 < rhs.0 } - internal func sort(lhs: (PBXObjectReference, PBXBuildFile), rhs: (PBXObjectReference, PBXBuildFile)) -> Bool { + func sort(lhs: (PBXObjectReference, PBXBuildFile), rhs: (PBXObjectReference, PBXBuildFile)) -> Bool { switch self { case .byFilename: return sortBuildFilesByName(lhs.1, rhs.1) @@ -53,7 +53,7 @@ public enum PBXFileOrder { } } - internal func sort(lhs: (PBXObjectReference, PBXBuildPhaseFile), rhs: (PBXObjectReference, PBXBuildPhaseFile)) -> Bool { + func sort(lhs: (PBXObjectReference, PBXBuildPhaseFile), rhs: (PBXObjectReference, PBXBuildPhaseFile)) -> Bool { switch self { case .byFilename: return sortBuildFilesByName(lhs.1.buildFile, rhs.1.buildFile) @@ -62,7 +62,7 @@ public enum PBXFileOrder { } } - internal func sort(lhs: (PBXObjectReference, PBXFileReference), rhs: (PBXObjectReference, PBXFileReference)) -> Bool { + func sort(lhs: (PBXObjectReference, PBXFileReference), rhs: (PBXObjectReference, PBXFileReference)) -> Bool { switch self { case .byFilename: return sortFileElementsByName(lhs.1, rhs.1) @@ -94,7 +94,7 @@ public enum PBXNavigatorFileOrder { /// Sorts the files by their file names with all groups appear at the top of the list. case byFilenameGroupsFirst - internal var sort: ((PBXFileElement, PBXFileElement) -> Bool)? { + var sort: ((PBXFileElement, PBXFileElement) -> Bool)? { switch self { case .byFilename: return { sortFileElementsByName($0, $1) } @@ -122,7 +122,7 @@ public enum PBXBuildPhaseFileOrder { /// Sort the files by their file name. This is a case sensitive sort with uppercase names appearing before lowercase names. case byFilename - internal var sort: ((PBXBuildFile, PBXBuildFile) -> Bool)? { + var sort: ((PBXBuildFile, PBXBuildFile) -> Bool)? { switch self { case .byFilename: return { lhs, rhs in diff --git a/Sources/XcodeProj/Objects/Project/PBXProj.swift b/Sources/XcodeProj/Objects/Project/PBXProj.swift index 6248aed4..48a6ee36 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProj.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProj.swift @@ -66,7 +66,7 @@ public final class PBXProj: Decodable { objects: pbxproj.objects ) } - + /// Initializes the project with the data representation of pbxproj file. /// /// - Parameters: @@ -331,7 +331,7 @@ extension PBXProj: Writable { let encoder = PBXProjEncoder(outputSettings: PBXOutputSettings()) return try encoder.encode(proj: self).data(using: .utf8) } - + public func write(path: Path, override: Bool) throws { try write(path: path, override: override, outputSettings: PBXOutputSettings()) } diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index 771e3897..9b0dd2f2 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -238,7 +238,7 @@ final class PBXProjEncoder { rootObject.value, comment: "Project object" ) - ), stateHolder: &stateHolder, to: &output) + ), stateHolder: &stateHolder, to: &output) writeDictionaryEnd(stateHolder: &stateHolder, to: &output) writeNewLine(stateHolder: &stateHolder, to: &output) @@ -287,12 +287,12 @@ final class PBXProjEncoder { output.append("/* \(comment) */") } - private func write(section: String, - proj: PBXProj, - objects: [PBXObjectReference: T], - outputSettings: PBXOutputSettings, - stateHolder: inout StateHolder, - to output: inout [String]) throws where T: PlistSerializable & Equatable { + private func write(section: String, + proj: PBXProj, + objects: [PBXObjectReference: some PlistSerializable & Equatable], + outputSettings: PBXOutputSettings, + stateHolder: inout StateHolder, + to output: inout [String]) throws { try write(section: section, proj: proj, objects: objects, sort: outputSettings.projFileListOrder.sort, stateHolder: &stateHolder, to: &output) } @@ -367,7 +367,7 @@ final class PBXProjEncoder { stateHolder: inout StateHolder, to output: inout [String]) { writeDictionaryStart(stateHolder: &stateHolder, to: &output) - let sorted = dictionary.sorted(by: { (left, right) -> Bool in + let sorted = dictionary.sorted(by: { left, right -> Bool in if left.key == "isa" { return true } else if right.key == "isa" { @@ -376,9 +376,9 @@ final class PBXProjEncoder { return left.key.string < right.key.string } }) - sorted.forEach { - write(dictionaryKey: $0.key, - dictionaryValue: $0.value, + for item in sorted { + write(dictionaryKey: item.key, + dictionaryValue: item.value, multiline: stateHolder.multiline, stateHolder: &stateHolder, to: &output) diff --git a/Sources/XcodeProj/Objects/Project/PBXProject.swift b/Sources/XcodeProj/Objects/Project/PBXProject.swift index 9a2ccd66..79a3e148 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProject.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProject.swift @@ -111,14 +111,14 @@ public final class PBXProject: PBXObject { public var targetAttributes: [PBXTarget: [String: Any]] { set { targetAttributeReferences = [:] - newValue.forEach { - targetAttributeReferences[$0.key.reference] = $0.value + for item in newValue { + targetAttributeReferences[item.key.reference] = item.value } } get { var attributes: [PBXTarget: [String: Any]] = [:] - targetAttributeReferences.forEach { - if let object: PBXTarget = $0.key.getObject() { - attributes[object] = $0.value + for targetAttributeReference in targetAttributeReferences { + if let object: PBXTarget = targetAttributeReference.key.getObject() { + attributes[object] = targetAttributeReference.value } } return attributes @@ -205,7 +205,7 @@ public final class PBXProject: PBXObject { productName: String, versionRequirement: XCRemoteSwiftPackageReference.VersionRequirement, targetName: String) throws -> XCRemoteSwiftPackageReference { - let objects = try self.objects() + let objects = try objects() guard let target = targets.first(where: { $0.name == targetName }) else { throw PBXProjError.targetNotFound(targetName: targetName) } @@ -243,7 +243,7 @@ public final class PBXProject: PBXObject { addFileReference: Bool = true) throws -> XCSwiftPackageProductDependency { guard path.isRelative else { throw PBXProjError.pathIsAbsolute(path) } - let objects = try self.objects() + let objects = try objects() guard let target = targets.first(where: { $0.name == targetName }) else { throw PBXProjError.targetNotFound(targetName: targetName) } @@ -356,14 +356,14 @@ public final class PBXProject: PBXObject { let container = try decoder.container(keyedBy: CodingKeys.self) let referenceRepository = decoder.context.objectReferenceRepository let objects = decoder.context.objects - name = (try container.decodeIfPresent(.name)) ?? "" + name = try (container.decodeIfPresent(.name)) ?? "" let buildConfigurationListReference: String = try container.decode(.buildConfigurationList) self.buildConfigurationListReference = referenceRepository.getOrCreate(reference: buildConfigurationListReference, objects: objects) compatibilityVersion = try container.decode(.compatibilityVersion) developmentRegion = try container.decodeIfPresent(.developmentRegion) let hasScannedForEncodingsString: String? = try container.decodeIfPresent(.hasScannedForEncodings) hasScannedForEncodings = hasScannedForEncodingsString.flatMap { Int($0) } ?? 0 - knownRegions = (try container.decodeIfPresent(.knownRegions)) ?? [] + knownRegions = try (container.decodeIfPresent(.knownRegions)) ?? [] let mainGroupReference: String = try container.decode(.mainGroup) self.mainGroupReference = referenceRepository.getOrCreate(reference: mainGroupReference, objects: objects) if let productRefGroupReference: String = try container.decodeIfPresent(.productRefGroup) { @@ -372,7 +372,7 @@ public final class PBXProject: PBXObject { productsGroupReference = nil } projectDirPath = try container.decodeIfPresent(.projectDirPath) ?? "" - let projectReferences: [[String: String]] = (try container.decodeIfPresent(.projectReferences)) ?? [] + let projectReferences: [[String: String]] = try (container.decodeIfPresent(.projectReferences)) ?? [] self.projectReferences = projectReferences.map { references in references.mapValues { referenceRepository.getOrCreate(reference: $0, objects: objects) } } @@ -383,13 +383,13 @@ public final class PBXProject: PBXObject { } else { projectRoots = [] } - let targetReferences: [String] = (try container.decodeIfPresent(.targets)) ?? [] + let targetReferences: [String] = try (container.decodeIfPresent(.targets)) ?? [] self.targetReferences = targetReferences.map { referenceRepository.getOrCreate(reference: $0, objects: objects) } let packageRefeferenceStrings: [String] = try container.decodeIfPresent(.packageReferences) ?? [] packageReferences = packageRefeferenceStrings.map { referenceRepository.getOrCreate(reference: $0, objects: objects) } - var attributes = (try container.decodeIfPresent([String: Any].self, forKey: .attributes) ?? [:]) + var attributes = try (container.decodeIfPresent([String: Any].self, forKey: .attributes) ?? [:]) var targetAttributeReferences: [PBXObjectReference: [String: Any]] = [:] if let targetAttributes = attributes[PBXProject.targetAttributesKey] as? [String: [String: Any]] { targetAttributes.forEach { targetAttributeReferences[referenceRepository.getOrCreate(reference: $0.key, objects: objects)] = $0.value } @@ -433,7 +433,7 @@ extension PBXProject { private func addSwiftPackageProduct(reference: XCRemoteSwiftPackageReference, productName: String, target: PBXTarget) throws -> XCSwiftPackageProductDependency { - let objects = try self.objects() + let objects = try objects() let productDependency: XCSwiftPackageProductDependency // Avoid duplication @@ -452,7 +452,7 @@ extension PBXProject { private func addLocalSwiftPackageProduct(path: Path, productName: String, target: PBXTarget) throws -> XCSwiftPackageProductDependency { - let objects = try self.objects() + let objects = try objects() let productDependency: XCSwiftPackageProductDependency // Avoid duplication @@ -483,7 +483,7 @@ extension PBXProject: PlistSerializable { comment: buildConfigurationListComment) dictionary["buildConfigurationList"] = .string(buildConfigurationListCommentedString) dictionary["compatibilityVersion"] = .string(CommentedString(compatibilityVersion)) - if let developmentRegion = developmentRegion { + if let developmentRegion { dictionary["developmentRegion"] = .string(CommentedString(developmentRegion)) } dictionary["hasScannedForEncodings"] = .string(CommentedString("\(hasScannedForEncodings)")) @@ -494,7 +494,7 @@ extension PBXProject: PlistSerializable { } let mainGroupObject: PBXGroup? = mainGroupReference.getObject() dictionary["mainGroup"] = .string(CommentedString(mainGroupReference.value, comment: mainGroupObject?.fileName())) - if let productsGroupReference = productsGroupReference { + if let productsGroupReference { let productRefGroupObject: PBXGroup? = productsGroupReference.getObject() dictionary["productRefGroup"] = .string(CommentedString(productsGroupReference.value, comment: productRefGroupObject?.fileName())) @@ -550,7 +550,8 @@ extension PBXProject: PlistSerializable { } return .array(projectReferences.compactMap { reference in guard let productGroupReference = reference[Xcode.ProjectReference.productGroupKey], - let projectRef = reference[Xcode.ProjectReference.projectReferenceKey] else { + let projectRef = reference[Xcode.ProjectReference.projectReferenceKey] + else { return nil } let producGroup: PBXGroup? = productGroupReference.getObject() diff --git a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift index 5d2a1943..c20d93c2 100644 --- a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift +++ b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift @@ -6,7 +6,7 @@ import Foundation extension PBXAggregateTarget { /// :nodoc: func isEqual(to rhs: PBXAggregateTarget) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } @@ -113,7 +113,7 @@ extension PBXFileReference { extension PBXFrameworksBuildPhase { /// :nodoc: func isEqual(to rhs: PBXFrameworksBuildPhase) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } @@ -128,7 +128,7 @@ extension PBXGroup { extension PBXHeadersBuildPhase { /// :nodoc: func isEqual(to rhs: PBXHeadersBuildPhase) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } @@ -187,14 +187,14 @@ extension PBXReferenceProxy { extension PBXResourcesBuildPhase { /// :nodoc: func isEqual(to rhs: PBXResourcesBuildPhase) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } extension PBXRezBuildPhase { /// :nodoc: func isEqual(to rhs: PBXRezBuildPhase) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } @@ -216,7 +216,7 @@ extension PBXShellScriptBuildPhase { extension PBXSourcesBuildPhase { /// :nodoc: func isEqual(to rhs: PBXSourcesBuildPhase) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } @@ -251,7 +251,7 @@ extension PBXTargetDependency { extension PBXVariantGroup { /// :nodoc: func isEqual(to rhs: PBXVariantGroup) -> Bool { - return super.isEqual(to: rhs) + super.isEqual(to: rhs) } } diff --git a/Sources/XcodeProj/Objects/SwiftPackage/XCRemoteSwiftPackageReference.swift b/Sources/XcodeProj/Objects/SwiftPackage/XCRemoteSwiftPackageReference.swift index 78b4a86f..3f8a4000 100644 --- a/Sources/XcodeProj/Objects/SwiftPackage/XCRemoteSwiftPackageReference.swift +++ b/Sources/XcodeProj/Objects/SwiftPackage/XCRemoteSwiftPackageReference.swift @@ -131,10 +131,10 @@ public class XCRemoteSwiftPackageReference: PBXContainerItem, PlistSerializable func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary = try super.plistValues(proj: proj, reference: reference) dictionary["isa"] = .string(CommentedString(XCRemoteSwiftPackageReference.isa)) - if let repositoryURL = repositoryURL { + if let repositoryURL { dictionary["repositoryURL"] = .string(.init(repositoryURL)) } - if let versionRequirement = versionRequirement { + if let versionRequirement { dictionary["requirement"] = PlistValue.dictionary(versionRequirement.plistValues()) } return (key: CommentedString(reference, comment: "XCRemoteSwiftPackageReference \"\(name ?? "")\""), diff --git a/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift b/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift index 238e31f9..cb0abc3d 100644 --- a/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift +++ b/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift @@ -57,7 +57,7 @@ public class XCSwiftPackageProductDependency: PBXContainerItem, PlistSerializabl func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary = try super.plistValues(proj: proj, reference: reference) dictionary["isa"] = .string(CommentedString(XCSwiftPackageProductDependency.isa)) - if let package = package { + if let package { dictionary["package"] = .string(.init(package.reference.value, comment: "XCRemoteSwiftPackageReference \"\(package.name ?? "")\"")) } if isPlugin { diff --git a/Sources/XcodeProj/Objects/Targets/PBXAggregateTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXAggregateTarget.swift index ec87371f..9bfd5674 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXAggregateTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXAggregateTarget.swift @@ -12,7 +12,7 @@ public final class PBXAggregateTarget: PBXTarget { extension PBXAggregateTarget: PlistSerializable { func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { - return try plistValues(proj: proj, isa: PBXAggregateTarget.isa, reference: reference) + try plistValues(proj: proj, isa: PBXAggregateTarget.isa, reference: reference) } } diff --git a/Sources/XcodeProj/Objects/Targets/PBXLegacyTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXLegacyTarget.swift index 1b858e8c..6d9a5e56 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXLegacyTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXLegacyTarget.swift @@ -79,16 +79,16 @@ public final class PBXLegacyTarget: PBXTarget { switch value { case let .dictionary(dictValue): dict = dictValue - if let buildToolPath = buildToolPath { + if let buildToolPath { dict["buildToolPath"] = PlistValue.string(CommentedString(buildToolPath)) } - if let buildArgumentsString = buildArgumentsString { + if let buildArgumentsString { dict["buildArgumentsString"] = PlistValue.string(CommentedString(buildArgumentsString)) } dict["passBuildSettingsInEnvironment"] = PlistValue.string(CommentedString(passBuildSettingsInEnvironment.int.description)) - if let buildWorkingDirectory = buildWorkingDirectory { + if let buildWorkingDirectory { dict["buildWorkingDirectory"] = PlistValue.string(CommentedString(buildWorkingDirectory)) } @@ -108,6 +108,6 @@ public final class PBXLegacyTarget: PBXTarget { extension PBXLegacyTarget: PlistSerializable { func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { - return try plistValues(proj: proj, isa: PBXLegacyTarget.isa, reference: reference) + try plistValues(proj: proj, isa: PBXLegacyTarget.isa, reference: reference) } } diff --git a/Sources/XcodeProj/Objects/Targets/PBXNativeTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXNativeTarget.swift index 45c4bbcb..c3705422 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXNativeTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXNativeTarget.swift @@ -54,7 +54,7 @@ public final class PBXNativeTarget: PBXTarget { guard case var PlistValue.dictionary(dict) = value else { throw XcodeprojWritingError.invalidType(class: String(describing: type(of: self)), expected: "Dictionary") } - if let productInstallPath = productInstallPath { + if let productInstallPath { dict["productInstallPath"] = .string(CommentedString(productInstallPath)) } return (key: key, value: .dictionary(dict)) @@ -70,7 +70,7 @@ public final class PBXNativeTarget: PBXTarget { extension PBXNativeTarget: PlistSerializable { func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { - return try plistValues(proj: proj, isa: PBXNativeTarget.isa, reference: reference) + try plistValues(proj: proj, isa: PBXNativeTarget.isa, reference: reference) } } diff --git a/Sources/XcodeProj/Objects/Targets/PBXProductType.swift b/Sources/XcodeProj/Objects/Targets/PBXProductType.swift index 21dbf8b7..785d1ec1 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXProductType.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXProductType.swift @@ -49,7 +49,7 @@ public enum PBXProductType: String, Decodable { case .unitTestBundle, .uiTestBundle: return "xctest" case .appExtension, .extensionKitExtension, .tvExtension, .watchExtension, .watch2Extension, .messagesExtension, .stickerPack, .xcodeExtension, - .intentsServiceExtension: + .intentsServiceExtension: return "appex" case .commandLineTool: return nil diff --git a/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift b/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift index 67363c58..9c34421e 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift @@ -64,10 +64,10 @@ public final class PBXReferenceProxy: PBXFileElement { fatalError("super implementation changed and we didn’t realise!") } dictionary["isa"] = .string(CommentedString(PBXReferenceProxy.isa)) - if let fileType = fileType { + if let fileType { dictionary["fileType"] = .string(CommentedString(fileType)) } - if let remoteReference = remoteReference { + if let remoteReference { dictionary["remoteRef"] = .string(CommentedString(remoteReference.value, comment: "PBXContainerItemProxy")) } return (key: CommentedString(reference, comment: path), diff --git a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift index 07d25549..86646cfd 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift @@ -174,7 +174,7 @@ public class PBXTarget: PBXContainerItem { var dictionary = try super.plistValues(proj: proj, reference: reference) dictionary["isa"] = .string(CommentedString(isa)) let buildConfigurationListComment = "Build configuration list for \(isa) \"\(name)\"" - if let buildConfigurationListReference = buildConfigurationListReference { + if let buildConfigurationListReference { dictionary["buildConfigurationList"] = .string(CommentedString(buildConfigurationListReference.value, comment: buildConfigurationListComment)) } @@ -191,13 +191,13 @@ public class PBXTarget: PBXContainerItem { dictionary["dependencies"] = .array(dependencyReferences.map { .string(CommentedString($0.value, comment: PBXTargetDependency.isa)) }) dictionary["name"] = .string(CommentedString(name)) - if let productName = productName { + if let productName { dictionary["productName"] = .string(CommentedString(productName)) } - if let productType = productType { + if let productType { dictionary["productType"] = .string(CommentedString(productType.rawValue)) } - if let productReference = productReference { + if let productReference { let fileElement: PBXFileElement? = productReference.getObject() dictionary["productReference"] = .string(CommentedString(productReference.value, comment: fileElement?.fileName())) } @@ -225,7 +225,7 @@ public extension PBXTarget { /// /// - Returns: product name with extension. func productNameWithExtension() -> String? { - guard let productName = self.productName else { return nil } + guard let productName else { return nil } guard let fileExtension = productType?.fileExtension else { return nil } return "\(productName).\(fileExtension)" } diff --git a/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift b/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift index 22603e5b..6da6ba0a 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift @@ -120,23 +120,23 @@ extension PBXTargetDependency: PlistSerializable { func plistKeyAndValue(proj _: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { var dictionary: [CommentedString: PlistValue] = [:] dictionary["isa"] = .string(CommentedString(PBXTargetDependency.isa)) - if let name = name { + if let name { dictionary["name"] = .string(CommentedString(name)) } - if let platformFilter = platformFilter { + if let platformFilter { dictionary["platformFilter"] = .string(CommentedString(platformFilter)) } - if let platformFilters = platformFilters { + if let platformFilters { dictionary["platformFilters"] = .array(platformFilters.map { .string(.init($0)) }) } - if let targetReference = targetReference { + if let targetReference { let targetObject: PBXTarget? = targetReference.getObject() dictionary["target"] = .string(CommentedString(targetReference.value, comment: targetObject?.name)) } - if let targetProxyReference = targetProxyReference { + if let targetProxyReference { dictionary["targetProxy"] = .string(CommentedString(targetProxyReference.value, comment: "PBXContainerItemProxy")) } - if let productReference = productReference { + if let productReference { dictionary["productRef"] = .string(CommentedString(productReference.value, comment: product?.productName)) } return (key: CommentedString(reference, diff --git a/Sources/XcodeProj/Project/WorkspaceSettings.swift b/Sources/XcodeProj/Project/WorkspaceSettings.swift index 343090fb..25eee302 100644 --- a/Sources/XcodeProj/Project/WorkspaceSettings.swift +++ b/Sources/XcodeProj/Project/WorkspaceSettings.swift @@ -59,8 +59,7 @@ public class WorkspaceSettings: Codable, Equatable, Writable { public init(buildSystem: BuildSystem = .new, derivedDataLocationStyle: DerivedDataLocationStyle? = nil, derivedDataCustomLocation: String? = nil, - autoCreateSchemes: Bool? = nil) - { + autoCreateSchemes: Bool? = nil) { self.buildSystem = buildSystem self.derivedDataLocationStyle = derivedDataLocationStyle self.derivedDataCustomLocation = derivedDataCustomLocation @@ -74,15 +73,13 @@ public class WorkspaceSettings: Codable, Equatable, Writable { public required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) if let buildSystemString: String = try container.decodeIfPresent(.buildSystem), - let buildSystem = BuildSystem(rawValue: buildSystemString) - { + let buildSystem = BuildSystem(rawValue: buildSystemString) { self.buildSystem = buildSystem } else { buildSystem = .new } if let derivedDataLocationStyleString: String = try container.decodeIfPresent(.derivedDataLocationStyle), - let derivedDataLocationStyle = DerivedDataLocationStyle(rawValue: derivedDataLocationStyleString) - { + let derivedDataLocationStyle = DerivedDataLocationStyle(rawValue: derivedDataLocationStyleString) { self.derivedDataLocationStyle = derivedDataLocationStyle } else { derivedDataLocationStyle = .default @@ -100,13 +97,13 @@ public class WorkspaceSettings: Codable, Equatable, Writable { if buildSystem == .original { try container.encode(buildSystem.rawValue, forKey: .buildSystem) } - if let derivedDataLocationStyle = derivedDataLocationStyle { + if let derivedDataLocationStyle { try container.encode(derivedDataLocationStyle.rawValue, forKey: .derivedDataLocationStyle) } - if let derivedDataCustomLocation = derivedDataCustomLocation { + if let derivedDataCustomLocation { try container.encode(derivedDataCustomLocation, forKey: .derivedDataCustomLocation) } - if let autoCreateSchemes = autoCreateSchemes { + if let autoCreateSchemes { try container.encode(autoCreateSchemes, forKey: .autoCreateSchemes) } } @@ -152,7 +149,7 @@ public class WorkspaceSettings: Codable, Equatable, Writable { } try path.write(data) } - + /// Get the workspace settings. /// /// - Throws: reading error if something goes wrong. diff --git a/Sources/XcodeProj/Project/XCBreakpointList.swift b/Sources/XcodeProj/Project/XCBreakpointList.swift index 361ce3e9..d253b533 100644 --- a/Sources/XcodeProj/Project/XCBreakpointList.swift +++ b/Sources/XcodeProj/Project/XCBreakpointList.swift @@ -70,7 +70,7 @@ public final class XCBreakpointList: Equatable, Writable { attributes["conveyanceType"] = conveyanceType attributes["command"] = command attributes["arguments"] = arguments - if let waitUntilDone = waitUntilDone { + if let waitUntilDone { attributes["waitUntilDone"] = waitUntilDone ? "YES" : "NO" } attributes["script"] = script @@ -123,7 +123,8 @@ public final class XCBreakpointList: Equatable, Writable { init(element: AEXMLElement) throws { guard let actionExtensionIDString = element.attributes["ActionExtensionID"], - let actionExtensionID = ActionExtensionID(rawValue: actionExtensionIDString) else { + let actionExtensionID = ActionExtensionID(rawValue: actionExtensionIDString) + else { throw XCBreakpointListError.missing(property: "ActionExtensionID") } self.actionExtensionID = actionExtensionID @@ -334,7 +335,8 @@ public final class XCBreakpointList: Equatable, Writable { init(element: AEXMLElement) throws { guard let breakpointExtensionIDString = element.attributes["BreakpointExtensionID"], - let breakpointExtensionID = BreakpointExtensionID(rawValue: breakpointExtensionIDString) else { + let breakpointExtensionID = BreakpointExtensionID(rawValue: breakpointExtensionIDString) + else { throw XCBreakpointListError.missing(property: "BreakpointExtensionID") } self.breakpointExtensionID = breakpointExtensionID @@ -375,7 +377,7 @@ public final class XCBreakpointList: Equatable, Writable { if !path.exists { throw XCBreakpointListError.notFound(path: path) } - let document = try AEXMLDocument(xml: try path.read()) + let document = try AEXMLDocument(xml: path.read()) let bucket = document["Bucket"] type = bucket.attributes["type"] version = bucket.attributes["version"] @@ -395,7 +397,7 @@ public final class XCBreakpointList: Equatable, Writable { // MARK: - Helpers public func add(breakpointProxy: BreakpointProxy) -> XCBreakpointList { - var breakpoints = self.breakpoints + var breakpoints = breakpoints breakpoints.append(breakpointProxy) return XCBreakpointList(type: type, version: version, breakpoints: breakpoints) } @@ -404,7 +406,7 @@ public final class XCBreakpointList: Equatable, Writable { public func write(path: Path, override: Bool) throws { let document = getAEXMLDocument() - + if override, path.exists { try path.delete() } @@ -437,12 +439,12 @@ public final class XCBreakpointList: Equatable, Writable { } } -extension XCBreakpointList { +public extension XCBreakpointList { /// Returns breakpoints plist path relative to the given path. /// /// - Parameter path: debugger folder /// - Returns: breakpoints plist path relative to the given path. - public static func path(_ path: Path) -> Path { + static func path(_ path: Path) -> Path { path + "Breakpoints_v2.xcbkptlist" } } diff --git a/Sources/XcodeProj/Project/XCSharedData.swift b/Sources/XcodeProj/Project/XCSharedData.swift index 9469970c..312a3913 100644 --- a/Sources/XcodeProj/Project/XCSharedData.swift +++ b/Sources/XcodeProj/Project/XCSharedData.swift @@ -87,12 +87,12 @@ public final class XCSharedData: Equatable, Writable { try debuggerPath.delete() } - guard let breakpoints = breakpoints else { return } + guard let breakpoints else { return } try debuggerPath.mkpath() try breakpoints.write(path: XCBreakpointList.path(debuggerPath), override: override) } - + func writeWorkspaceSettings(path: Path, override: Bool) throws { /** * We don't want to delete this path when `override` is `true` because @@ -103,17 +103,17 @@ public final class XCSharedData: Equatable, Writable { if !path.exists { try path.mkpath() } - + try workspaceSettings?.write(path: WorkspaceSettings.path(path), override: override) } } -extension XCSharedData { +public extension XCSharedData { /// Returns shared data path relative to the given path. /// /// - Parameter path: `.xcodeproj` file path /// - Returns: shared data path relative to the given path. - public static func path(_ path: Path) -> Path { + static func path(_ path: Path) -> Path { path + "xcshareddata" } } diff --git a/Sources/XcodeProj/Project/XCUserData.swift b/Sources/XcodeProj/Project/XCUserData.swift index 1d3bf328..272152b5 100644 --- a/Sources/XcodeProj/Project/XCUserData.swift +++ b/Sources/XcodeProj/Project/XCUserData.swift @@ -1,6 +1,6 @@ +import AEXML import Foundation import PathKit -import AEXML public final class XCUserData: Equatable, Writable { // MARK: - Attributes @@ -82,7 +82,7 @@ public final class XCUserData: Equatable, Writable { } func writeSchemeManagement(path: Path, override: Bool) throws { - guard let schemeManagement = schemeManagement else { return } + guard let schemeManagement else { return } let schemesPath = XCScheme.schemesPath(path) try schemesPath.mkpath() @@ -90,7 +90,7 @@ public final class XCUserData: Equatable, Writable { } func writeBreakpoints(path: Path, override: Bool) throws { - guard let breakpoints = breakpoints else { return } + guard let breakpoints else { return } let debuggerPath = XCDebugger.path(path) try debuggerPath.mkpath() @@ -98,12 +98,12 @@ public final class XCUserData: Equatable, Writable { } } -extension XCUserData { +public extension XCUserData { /// Returns user data path relative to the given path. /// /// - Parameter path: `.xcodeproj` file path /// - Returns: user data path relative to the given path. - public static func path(_ path: Path) -> Path { + static func path(_ path: Path) -> Path { path + "xcuserdata" } @@ -111,7 +111,7 @@ extension XCUserData { /// /// - Parameter path: `.xcodeproj` file path /// - Returns: user data path relative to the given path. - public static func path(_ path: Path, userName: String) -> Path { + static func path(_ path: Path, userName: String) -> Path { XCUserData.path(path) + "\(userName).xcuserdatad" } } diff --git a/Sources/XcodeProj/Project/Xcode.swift b/Sources/XcodeProj/Project/Xcode.swift index 5b2b1747..907fc5a0 100644 --- a/Sources/XcodeProj/Project/Xcode.swift +++ b/Sources/XcodeProj/Project/Xcode.swift @@ -1,11 +1,11 @@ import Foundation /// Class that contains Xcode constants. -public struct Xcode { +public enum Xcode { /// Last known constants. - public struct LastKnown { + public enum LastKnown { /// Last known SDKs. - public struct SDK { + public enum SDK { /// Last known SDK for iOS. public static let ios: String = "14.0" @@ -36,7 +36,7 @@ public struct Xcode { } /// Default values. - public struct Default { + public enum Default { /// The default object version for Xcodeproj. public static let objectVersion: UInt = 46 @@ -45,13 +45,13 @@ public struct Xcode { /// Default development region. public static let developmentRegion: String = "en" - + /// Default XCScheme format version public static let xcschemeFormatVersion: String = "1.3" - + /// The last Swift upgrade check version public static let lastSwiftUpgradeCheck: String = "1300" - + /// The last known Xcode upgrade check version. public static let lastUpgradeCheck: String = "1300" } @@ -63,7 +63,7 @@ public struct Xcode { public static let headersExtensions = [".h", ".hh", ".hpp", ".ipp", ".tpp", ".hxx", ".def", ".inl", ".inc", ".pch"] /// Supported values. - public struct Supported { + public enum Supported { /// The version of `.xcscheme` files supported by Xcodeproj public static let xcschemeFormatVersion = "1.3" } @@ -350,7 +350,7 @@ public struct Xcode { ] /// Remote project reference dictionary keys. - public struct ProjectReference { + public enum ProjectReference { public static let projectReferenceKey = "ProjectRef" public static let productGroupKey = "ProductGroup" } diff --git a/Sources/XcodeProj/Protocols/Writable.swift b/Sources/XcodeProj/Protocols/Writable.swift index b2145675..f4a7016d 100644 --- a/Sources/XcodeProj/Protocols/Writable.swift +++ b/Sources/XcodeProj/Protocols/Writable.swift @@ -23,11 +23,11 @@ public protocol Writable { func dataRepresentation() throws -> Data? } -extension Writable { - public func write(pathString: String, override: Bool) throws { +public extension Writable { + func write(pathString: String, override: Bool) throws { let path = Path(pathString) try write(path: path, override: override) } - public func dataRepresentation() throws -> Data? { nil } + func dataRepresentation() throws -> Data? { nil } } diff --git a/Sources/XcodeProj/Scheme/XCScheme+AditionalOption.swift b/Sources/XcodeProj/Scheme/XCScheme+AditionalOption.swift index 5e643047..3f412209 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+AditionalOption.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+AditionalOption.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class AdditionalOption: Equatable { +public extension XCScheme { + final class AdditionalOption: Equatable { // MARK: - Attributes public var key: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+AnalyzeAction.swift b/Sources/XcodeProj/Scheme/XCScheme+AnalyzeAction.swift index 2a295e7e..6dd25fb9 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+AnalyzeAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+AnalyzeAction.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class AnalyzeAction: Equatable { +public extension XCScheme { + final class AnalyzeAction: Equatable { // MARK: - Static // Xcode disables PreActions and PostActions for Analyze actions, so this Action diff --git a/Sources/XcodeProj/Scheme/XCScheme+ArchiveAction.swift b/Sources/XcodeProj/Scheme/XCScheme+ArchiveAction.swift index 92ddab9c..73cbae33 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+ArchiveAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+ArchiveAction.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class ArchiveAction: SerialAction { +public extension XCScheme { + final class ArchiveAction: SerialAction { // MARK: - Static private static let defaultBuildConfiguration = "Release" diff --git a/Sources/XcodeProj/Scheme/XCScheme+BuildAction.swift b/Sources/XcodeProj/Scheme/XCScheme+BuildAction.swift index f6e81bfd..8cc9ed15 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+BuildAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+BuildAction.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class BuildAction: SerialAction { +public extension XCScheme { + final class BuildAction: SerialAction { public final class Entry: Equatable { public enum BuildFor: Sendable { case running, testing, profiling, archiving, analyzing @@ -140,7 +140,7 @@ extension XCScheme { // MARK: - Helpers public func add(buildActionEntry: Entry) -> BuildAction { - var buildActionEntries = self.buildActionEntries + var buildActionEntries = buildActionEntries buildActionEntries.append(buildActionEntry) return BuildAction(buildActionEntries: buildActionEntries, parallelizeBuild: parallelizeBuild) @@ -158,7 +158,7 @@ extension XCScheme { attributes["buildArchitectures"] = buildArchitecturesXMLString } - if let runPostActionsOnFailure = runPostActionsOnFailure { + if let runPostActionsOnFailure { attributes["runPostActionsOnFailure"] = runPostActionsOnFailure.xmlString } @@ -167,7 +167,7 @@ extension XCScheme { attributes: attributes) super.writeXML(parent: element) let entries = element.addChild(name: "BuildActionEntries") - buildActionEntries.forEach { entry in + for entry in buildActionEntries { entries.addChild(entry.xmlElement()) } return element diff --git a/Sources/XcodeProj/Scheme/XCScheme+BuildableProductRunnable.swift b/Sources/XcodeProj/Scheme/XCScheme+BuildableProductRunnable.swift index 2dffa070..e590e8f3 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+BuildableProductRunnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+BuildableProductRunnable.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class BuildableProductRunnable: Runnable { +public extension XCScheme { + final class BuildableProductRunnable: Runnable { // MARK: - XML override func xmlElement() -> AEXMLElement { diff --git a/Sources/XcodeProj/Scheme/XCScheme+BuildableReference.swift b/Sources/XcodeProj/Scheme/XCScheme+BuildableReference.swift index f35011ed..5ded8df2 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+BuildableReference.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+BuildableReference.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class BuildableReference: Equatable, Hashable { +public extension XCScheme { + final class BuildableReference: Equatable, Hashable { // MARK: - Attributes public var referencedContainer: String @@ -52,7 +52,7 @@ extension XCScheme { blueprintName: String, buildableIdentifier: String = "primary") { self.referencedContainer = referencedContainer - self.blueprint = blueprintIdentifier.map(Blueprint.string) + blueprint = blueprintIdentifier.map(Blueprint.string) self.buildableName = buildableName self.buildableIdentifier = buildableIdentifier self.blueprintName = blueprintName @@ -75,7 +75,7 @@ extension XCScheme { } self.buildableIdentifier = buildableIdentifier let blueprintIdentifier = element.attributes["BlueprintIdentifier"] - self.blueprint = blueprintIdentifier.map(Blueprint.string) + blueprint = blueprintIdentifier.map(Blueprint.string) self.buildableName = buildableName self.blueprintName = blueprintName self.referencedContainer = referencedContainer diff --git a/Sources/XcodeProj/Scheme/XCScheme+CommandLineArguments.swift b/Sources/XcodeProj/Scheme/XCScheme+CommandLineArguments.swift index 80330a24..862299b3 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+CommandLineArguments.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+CommandLineArguments.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class CommandLineArguments: Equatable { +public extension XCScheme { + final class CommandLineArguments: Equatable { // MARK: - Attributes public let arguments: [CommandLineArgument] @@ -30,7 +30,7 @@ extension XCScheme { func xmlElement() -> AEXMLElement { let element = AEXMLElement(name: "CommandLineArguments", value: nil) - arguments.forEach { arg in + for arg in arguments { element.addChild(arg.xmlElement()) } return element @@ -44,8 +44,8 @@ extension XCScheme { } } -extension XCScheme.CommandLineArguments { - public struct CommandLineArgument: Equatable { +public extension XCScheme.CommandLineArguments { + struct CommandLineArgument: Equatable { // MARK: - Attributes public let name: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+EnvironmentVariable.swift b/Sources/XcodeProj/Scheme/XCScheme+EnvironmentVariable.swift index 2f625106..7fe613ee 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+EnvironmentVariable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+EnvironmentVariable.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public struct EnvironmentVariable: Equatable { +public extension XCScheme { + struct EnvironmentVariable: Equatable { // MARK: - Attributes public let variable: String @@ -44,7 +44,7 @@ extension XCScheme { static func xmlElement(from variables: [EnvironmentVariable]) -> AEXMLElement { let element = AEXMLElement(name: "EnvironmentVariables", value: nil) - variables.forEach { arg in + for arg in variables { element.addChild(arg.xmlElement()) } diff --git a/Sources/XcodeProj/Scheme/XCScheme+ExecutionAction.swift b/Sources/XcodeProj/Scheme/XCScheme+ExecutionAction.swift index 484e99aa..2a9aed87 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+ExecutionAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+ExecutionAction.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class ExecutionAction: Equatable { +public extension XCScheme { + final class ExecutionAction: Equatable { private static let ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction" // MARK: - Attributes @@ -45,14 +45,14 @@ extension XCScheme { "title": title, "scriptText": scriptText, ] - if let shellToInvoke = shellToInvoke { + if let shellToInvoke { attributes["shellToInvoke"] = shellToInvoke } let content = AEXMLElement(name: "ActionContent", value: nil, attributes: attributes) element.addChild(content) - if let environmentBuildable = environmentBuildable { + if let environmentBuildable { let environment = content.addChild(name: "EnvironmentBuildable") environment.addChild(environmentBuildable.xmlElement()) } diff --git a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift index a8770502..4edd8977 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift @@ -2,9 +2,9 @@ import AEXML import Foundation import PathKit -extension XCScheme { +public extension XCScheme { // swiftlint:disable:next type_body_length - public final class LaunchAction: SerialAction { + final class LaunchAction: SerialAction { public enum Style: String, Sendable { case auto = "0" case wait = "1" @@ -18,7 +18,7 @@ extension XCScheme { case disabled = "3" } - // The value used to disable 'API Validation'. + // The value used to disable 'API Validation'. // If this feature is not being disabled, this value will not be present. public let gpuValidationModeDisableValue = "1" @@ -263,7 +263,7 @@ extension XCScheme { "allowLocationSimulation": allowLocationSimulation.xmlString, ] - if let askForAppToLaunch = askForAppToLaunch { + if let askForAppToLaunch { attributes["askForAppToLaunch"] = askForAppToLaunch.xmlString } if enableGPUFrameCaptureMode != LaunchAction.defaultGPUFrameCaptureMode { @@ -308,7 +308,7 @@ extension XCScheme { if stopOnEveryMainThreadCheckerIssue { attributes["stopOnEveryMainThreadCheckerIssue"] = stopOnEveryMainThreadCheckerIssue.xmlString } - if let customWorkingDirectory = customWorkingDirectory { + if let customWorkingDirectory { attributes["customWorkingDirectory"] = customWorkingDirectory } @@ -320,36 +320,36 @@ extension XCScheme { value: nil, attributes: xmlAttributes) super.writeXML(parent: element) - if let runnable = runnable { + if let runnable { element.addChild(runnable.xmlElement()) } - if let pathRunnable = pathRunnable { + if let pathRunnable { element.addChild(pathRunnable.xmlElement()) } - if let locationScenarioReference = locationScenarioReference { + if let locationScenarioReference { element.addChild(locationScenarioReference.xmlElement()) } - if let macroExpansion = macroExpansion { + if let macroExpansion { let macro = element.addChild(name: "MacroExpansion") macro.addChild(macroExpansion.xmlElement()) } - if let commandlineArguments = commandlineArguments { + if let commandlineArguments { element.addChild(commandlineArguments.xmlElement()) } - if let environmentVariables = environmentVariables { + if let environmentVariables { element.addChild(EnvironmentVariable.xmlElement(from: environmentVariables)) } - if let language = language { + if let language { element.attributes["language"] = language } - if let region = region { + if let region { element.attributes["region"] = region } @@ -357,25 +357,25 @@ extension XCScheme { element.attributes["showNonLocalizedStrings"] = showNonLocalizedStrings.xmlString } - if let launchAutomaticallySubstyle = launchAutomaticallySubstyle { + if let launchAutomaticallySubstyle { element.attributes["launchAutomaticallySubstyle"] = launchAutomaticallySubstyle } - if let storeKitConfigurationFileReference = storeKitConfigurationFileReference { + if let storeKitConfigurationFileReference { element.addChild(storeKitConfigurationFileReference.xmlElement()) } - if let customLaunchCommand = customLaunchCommand { + if let customLaunchCommand { element.attributes["customLaunchCommand"] = customLaunchCommand } - if let customLLDBInitFile = customLLDBInitFile { + if let customLLDBInitFile { element.attributes["customLLDBInitFile"] = customLLDBInitFile } if !additionalOptions.isEmpty { let additionalOptionsElement = element.addChild(AEXMLElement(name: "AdditionalOptions")) - additionalOptions.forEach { additionalOption in + for additionalOption in additionalOptions { additionalOptionsElement.addChild(additionalOption.xmlElement()) } } diff --git a/Sources/XcodeProj/Scheme/XCScheme+LocationScenarioReference.swift b/Sources/XcodeProj/Scheme/XCScheme+LocationScenarioReference.swift index 23e13bb8..64bb69db 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+LocationScenarioReference.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+LocationScenarioReference.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class LocationScenarioReference: Equatable { +public extension XCScheme { + final class LocationScenarioReference: Equatable { // MARK: - Attributes public var identifier: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift b/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift index d47a1925..220de342 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public class PathRunnable: Equatable { +public extension XCScheme { + class PathRunnable: Equatable { // MARK: - Attributes public var runnableDebuggingMode: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift b/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift index 023b7957..6c486499 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift @@ -2,8 +2,8 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class ProfileAction: SerialAction { +public extension XCScheme { + final class ProfileAction: SerialAction { // MARK: - Static private static let defaultBuildConfiguration = "Release" @@ -15,6 +15,7 @@ extension XCScheme { // For backwards compatibility - can be removed in the next major version runnable as? BuildableProductRunnable } + public var buildConfiguration: String public var shouldUseLaunchSchemeArgsEnv: Bool public var savedToolIdentifier: String @@ -80,8 +81,8 @@ extension XCScheme { commandlineArguments: CommandLineArguments? = nil, environmentVariables: [EnvironmentVariable]? = nil, enableTestabilityWhenProfilingTests: Bool = true, - launchAutomaticallySubstyle: String? = nil) - { + launchAutomaticallySubstyle: String? = nil + ) { self.init( runnable: buildableProductRunnable, buildConfiguration: buildConfiguration, @@ -98,7 +99,8 @@ extension XCScheme { commandlineArguments: commandlineArguments, environmentVariables: environmentVariables, enableTestabilityWhenProfilingTests: enableTestabilityWhenProfilingTests, - launchAutomaticallySubstyle: launchAutomaticallySubstyle) + launchAutomaticallySubstyle: launchAutomaticallySubstyle + ) } override init(element: AEXMLElement) throws { @@ -152,10 +154,10 @@ extension XCScheme { "debugDocumentVersioning": debugDocumentVersioning.xmlString, ]) super.writeXML(parent: element) - if let runnable = runnable { + if let runnable { element.addChild(runnable.xmlElement()) } - if let askForAppToLaunch = askForAppToLaunch { + if let askForAppToLaunch { element.attributes["askForAppToLaunch"] = askForAppToLaunch.xmlString } if ignoresPersistentStateOnLaunch { @@ -164,20 +166,20 @@ extension XCScheme { if !enableTestabilityWhenProfilingTests { element.attributes["enableTestabilityWhenProfilingTests"] = "No" } - if let commandlineArguments = commandlineArguments { + if let commandlineArguments { element.addChild(commandlineArguments.xmlElement()) } - if let environmentVariables = environmentVariables { + if let environmentVariables { element.addChild(EnvironmentVariable.xmlElement(from: environmentVariables)) } - if let launchAutomaticallySubstyle = launchAutomaticallySubstyle { + if let launchAutomaticallySubstyle { element.attributes["launchAutomaticallySubstyle"] = launchAutomaticallySubstyle } - if let customWorkingDirectory = customWorkingDirectory { + if let customWorkingDirectory { element.attributes["customWorkingDirectory"] = customWorkingDirectory } - if let macroExpansion = macroExpansion { + if let macroExpansion { let macro = element.addChild(name: "MacroExpansion") macro.addChild(macroExpansion.xmlElement()) } diff --git a/Sources/XcodeProj/Scheme/XCScheme+RemoteRunnable.swift b/Sources/XcodeProj/Scheme/XCScheme+RemoteRunnable.swift index 67413e5c..b66cadd6 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+RemoteRunnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+RemoteRunnable.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class RemoteRunnable: Runnable { +public extension XCScheme { + final class RemoteRunnable: Runnable { // MARK: - Attributes public var bundleIdentifier: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift b/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift index b7173dc2..27471e9f 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public class Runnable: Equatable { +public extension XCScheme { + class Runnable: Equatable { // MARK: - Attributes public var runnableDebuggingMode: String @@ -27,7 +27,7 @@ extension XCScheme { let element = AEXMLElement(name: "Runnable", value: nil, attributes: ["runnableDebuggingMode": runnableDebuggingMode]) - if let buildableReference = buildableReference { + if let buildableReference { element.addChild(buildableReference.xmlElement()) } return element diff --git a/Sources/XcodeProj/Scheme/XCScheme+SerialAction.swift b/Sources/XcodeProj/Scheme/XCScheme+SerialAction.swift index 4a02b06b..fb842834 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+SerialAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+SerialAction.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public class SerialAction: Equatable { +public extension XCScheme { + class SerialAction: Equatable { // MARK: - Attributes public var preActions: [ExecutionAction] @@ -25,13 +25,13 @@ extension XCScheme { func writeXML(parent element: AEXMLElement) { if !preActions.isEmpty { let preActions = element.addChild(name: "PreActions") - self.preActions.forEach { preAction in + for preAction in self.preActions { preActions.addChild(preAction.xmlElement()) } } if !postActions.isEmpty { let postActions = element.addChild(name: "PostActions") - self.postActions.forEach { postAction in + for postAction in self.postActions { postActions.addChild(postAction.xmlElement()) } } diff --git a/Sources/XcodeProj/Scheme/XCScheme+StoreKitConfigurationFileReference.swift b/Sources/XcodeProj/Scheme/XCScheme+StoreKitConfigurationFileReference.swift index ab42e2af..4edc620d 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+StoreKitConfigurationFileReference.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+StoreKitConfigurationFileReference.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class StoreKitConfigurationFileReference: Equatable { +public extension XCScheme { + final class StoreKitConfigurationFileReference: Equatable { // MARK: - Attributes public var identifier: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+TestAction.swift b/Sources/XcodeProj/Scheme/XCScheme+TestAction.swift index 0c7c3f70..735e699b 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+TestAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+TestAction.swift @@ -2,12 +2,12 @@ import AEXML import Foundation import PathKit -extension XCScheme { - public final class TestAction: SerialAction { +public extension XCScheme { + final class TestAction: SerialAction { public enum AttachmentLifetime: String { case keepAlways, keepNever } - + public enum ScreenCaptureFormat: String { case screenshots, screenRecording } @@ -159,7 +159,7 @@ extension XCScheme { attributes["buildConfiguration"] = buildConfiguration attributes["selectedDebuggerIdentifier"] = selectedDebuggerIdentifier attributes["selectedLauncherIdentifier"] = selectedLauncherIdentifier - if let language = language { + if let language { attributes["language"] = language } attributes["region"] = region @@ -167,7 +167,7 @@ extension XCScheme { if codeCoverageEnabled { attributes["codeCoverageEnabled"] = codeCoverageEnabled.xmlString } - if let onlyGenerateCoverageForSpecifiedTargets = onlyGenerateCoverageForSpecifiedTargets { + if let onlyGenerateCoverageForSpecifiedTargets { attributes["onlyGenerateCoverageForSpecifiedTargets"] = onlyGenerateCoverageForSpecifiedTargets.xmlString } if enableAddressSanitizer { @@ -186,59 +186,59 @@ extension XCScheme { attributes["disableMainThreadChecker"] = disableMainThreadChecker.xmlString } attributes["systemAttachmentLifetime"] = systemAttachmentLifetime?.rawValue - + switch preferredScreenCaptureFormat { case .screenshots: attributes["preferredScreenCaptureFormat"] = preferredScreenCaptureFormat?.rawValue case .none, .screenRecording: break } - + if case .keepAlways? = userAttachmentLifetime { attributes["userAttachmentLifetime"] = userAttachmentLifetime?.rawValue } - if let customLLDBInitFile = customLLDBInitFile { + if let customLLDBInitFile { attributes["customLLDBInitFile"] = customLLDBInitFile } let element = AEXMLElement(name: "TestAction", value: nil, attributes: attributes) super.writeXML(parent: element) - if let testPlans = testPlans { + if let testPlans { let testPlansElement = element.addChild(name: "TestPlans") - testPlans.forEach { testPlan in + for testPlan in testPlans { testPlansElement.addChild(testPlan.xmlElement()) } } - if let macroExpansion = macroExpansion { + if let macroExpansion { let macro = element.addChild(name: "MacroExpansion") macro.addChild(macroExpansion.xmlElement()) } let testablesElement = element.addChild(name: "Testables") - testables.forEach { testable in + for testable in testables { testablesElement.addChild(testable.xmlElement()) } - if let commandlineArguments = commandlineArguments { + if let commandlineArguments { element.addChild(commandlineArguments.xmlElement()) } - if let environmentVariables = environmentVariables { + if let environmentVariables { element.addChild(EnvironmentVariable.xmlElement(from: environmentVariables)) } if !additionalOptions.isEmpty { let additionalOptionsElement = element.addChild(AEXMLElement(name: "AdditionalOptions")) - additionalOptions.forEach { additionalOption in + for additionalOption in additionalOptions { additionalOptionsElement.addChild(additionalOption.xmlElement()) } } if !codeCoverageTargets.isEmpty { let codeCoverageTargetsElement = element.addChild(AEXMLElement(name: "CodeCoverageTargets")) - codeCoverageTargets.forEach { target in + for target in codeCoverageTargets { codeCoverageTargetsElement.addChild(target.xmlElement()) } } diff --git a/Sources/XcodeProj/Scheme/XCScheme+TestItem.swift b/Sources/XcodeProj/Scheme/XCScheme+TestItem.swift index 02934909..9ede59f0 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+TestItem.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+TestItem.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class TestItem: Equatable { +public extension XCScheme { + final class TestItem: Equatable { // MARK: - Attributes public var identifier: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+TestPlanReference.swift b/Sources/XcodeProj/Scheme/XCScheme+TestPlanReference.swift index 1397391f..0c8e3f19 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+TestPlanReference.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+TestPlanReference.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class TestPlanReference: Equatable { +public extension XCScheme { + final class TestPlanReference: Equatable { // MARK: - Attributes public var reference: String diff --git a/Sources/XcodeProj/Scheme/XCScheme+TestableReference.swift b/Sources/XcodeProj/Scheme/XCScheme+TestableReference.swift index ac73ba3a..88b5bd1b 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+TestableReference.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+TestableReference.swift @@ -1,8 +1,8 @@ import AEXML import Foundation -extension XCScheme { - public final class TestableReference: Equatable { +public extension XCScheme { + final class TestableReference: Equatable { // MARK: - Attributes public var skipped: Bool @@ -40,7 +40,7 @@ extension XCScheme { useTestSelectionWhitelist = element.attributes["useTestSelectionWhitelist"] == "YES" randomExecutionOrdering = element.attributes["testExecutionOrdering"] == "random" buildableReference = try BuildableReference(element: element["BuildableReference"]) - + if element["LocationScenarioReference"].all?.first != nil { locationScenarioReference = try LocationScenarioReference(element: element["LocationScenarioReference"]) } else { @@ -64,7 +64,7 @@ extension XCScheme { func xmlElement() -> AEXMLElement { var attributes: [String: String] = ["skipped": skipped.xmlString] attributes["parallelizable"] = parallelizable ? parallelizable.xmlString : nil - if let useTestSelectionWhitelist = useTestSelectionWhitelist { + if let useTestSelectionWhitelist { attributes["useTestSelectionWhitelist"] = useTestSelectionWhitelist.xmlString } attributes["testExecutionOrdering"] = randomExecutionOrdering ? "random" : nil @@ -73,21 +73,21 @@ extension XCScheme { attributes: attributes) element.addChild(buildableReference.xmlElement()) - if let locationScenarioReference = locationScenarioReference { + if let locationScenarioReference { element.addChild(locationScenarioReference.xmlElement()) } - + if useTestSelectionWhitelist == true { if !selectedTests.isEmpty { let selectedTestsElement = element.addChild(name: "SelectedTests") - selectedTests.forEach { selectedTest in + for selectedTest in selectedTests { selectedTestsElement.addChild(selectedTest.xmlElement()) } } } else { if !skippedTests.isEmpty { let skippedTestsElement = element.addChild(name: "SkippedTests") - skippedTests.forEach { skippedTest in + for skippedTest in skippedTests { skippedTestsElement.addChild(skippedTest.xmlElement()) } } diff --git a/Sources/XcodeProj/Scheme/XCScheme.swift b/Sources/XcodeProj/Scheme/XCScheme.swift index 7a805c25..33130c9f 100644 --- a/Sources/XcodeProj/Scheme/XCScheme.swift +++ b/Sources/XcodeProj/Scheme/XCScheme.swift @@ -42,7 +42,7 @@ public final class XCScheme: Writable, Equatable { throw XCSchemeError.notFound(path: path) } name = path.lastComponentWithoutExtension - let document = try AEXMLDocument(xml: try path.read()) + let document = try AEXMLDocument(xml: path.read()) let scheme = document["Scheme"] lastUpgradeVersion = scheme.attributes["LastUpgradeVersion"] version = scheme.attributes["version"] @@ -93,36 +93,36 @@ public final class XCScheme: Writable, Equatable { } try path.write(document.xmlXcodeFormat) } - + public func dataRepresentation() throws -> Data? { getAEXMLDocument().xmlXcodeFormat.data(using: .utf8) } - + private func getAEXMLDocument() -> AEXMLDocument { let document = AEXMLDocument() var schemeAttributes: [String: String] = [:] schemeAttributes["LastUpgradeVersion"] = lastUpgradeVersion schemeAttributes["version"] = version let scheme = document.addChild(name: "Scheme", value: nil, attributes: schemeAttributes) - if let buildAction = buildAction { + if let buildAction { scheme.addChild(buildAction.xmlElement()) } - if let testAction = testAction { + if let testAction { scheme.addChild(testAction.xmlElement()) } - if let launchAction = launchAction { + if let launchAction { scheme.addChild(launchAction.xmlElement()) } - if let profileAction = profileAction { + if let profileAction { scheme.addChild(profileAction.xmlElement()) } - if let analyzeAction = analyzeAction { + if let analyzeAction { scheme.addChild(analyzeAction.xmlElement()) } - if let archiveAction = archiveAction { + if let archiveAction { scheme.addChild(archiveAction.xmlElement()) } - if let wasCreatedForAppExtension = wasCreatedForAppExtension { + if let wasCreatedForAppExtension { scheme.attributes["wasCreatedForAppExtension"] = wasCreatedForAppExtension.xmlString } return document diff --git a/Sources/XcodeProj/Scheme/XCSchemeManagement.swift b/Sources/XcodeProj/Scheme/XCSchemeManagement.swift index d9c06883..992c8f7d 100644 --- a/Sources/XcodeProj/Scheme/XCSchemeManagement.swift +++ b/Sources/XcodeProj/Scheme/XCSchemeManagement.swift @@ -4,16 +4,16 @@ import Foundation 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) - + public var description: String { switch self { case let .notFound(path): return "Couldn't initialize XCSchemeManagement because the file at path \(path.string) was not found." } } - + public var errorDescription: String? { - return description + description } } @@ -24,10 +24,9 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { public struct AutocreationBuildable: Equatable, Codable { var primary: Bool } - + /// Scheme configuration object. public struct UserStateScheme: Equatable, Codable { - /// Coding keys public enum CodingKeys: String, CodingKey { case shared @@ -38,25 +37,25 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { /// Name of the scheme (with the .xcscheme extension) public var name: String - + /// True if the scheme should be shared. public var shared: Bool - + /// Attribute used by Xcode to sort the schemes. public var orderHint: Int? - + /// True if the scheme should be shown in the list of schemes. public var isShown: Bool? - + /// The key that should be used when encoding the scheme configuration. var key: String { - var key = name - if shared { - key.append("_^#shared#^_") - } - return key - } - + var key = name + if shared { + key.append("_^#shared#^_") + } + return key + } + /// It initializes the scheme configuration with its attributes. /// - Parameters: /// - name: Name of the scheme (with the .xcscheme extension) @@ -72,23 +71,23 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { self.orderHint = orderHint self.isShown = isShown } - + // MARK: - Codable - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.orderHint = try container.decodeIfPresent(.orderHint) - self.isShown = try container.decodeIfPresent(.isShown) - self.shared = try container.decodeIfPresent(.shared) ?? false - self.name = try container.decode(.name) + orderHint = try container.decodeIfPresent(.orderHint) + isShown = try container.decodeIfPresent(.isShown) + shared = try container.decodeIfPresent(.shared) ?? false + name = try container.decode(.name) } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if let orderHint = orderHint { + if let orderHint { try container.encode(orderHint, forKey: .orderHint) } - if let isShown = isShown { + if let isShown { try container.encode(isShown, forKey: .isShown) } } @@ -99,10 +98,10 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { case schemeUserState = "SchemeUserState" case suppressBuildableAutocreation = "SuppressBuildableAutocreation" } - + /// An array that contains the configuration of the schemes. public var schemeUserState: [XCSchemeManagement.UserStateScheme]? - + /// A dictionary where the key is the object reference of the target, and the value the configuration for auto-creating schemes. public var suppressBuildableAutocreation: [String: XCSchemeManagement.AutocreationBuildable]? @@ -115,7 +114,7 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { self.schemeUserState = schemeUserState self.suppressBuildableAutocreation = suppressBuildableAutocreation } - + /// Initializes the XCSchemeManagement instance by parsing an existing xcschememanagement.plist /// - Parameter path: Path to the xcschememanagement.plist file. /// - Throws: An error if the file is malformated. @@ -124,9 +123,9 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { throw XCSchemeManagementError.notFound(path: path) } let decoder = XcodeprojPropertyListDecoder() - self = try decoder.decode(XCSchemeManagement.self, from: try path.read()) + self = try decoder.decode(XCSchemeManagement.self, from: path.read()) } - + /// Converts the object into a property list and writes it at the given path. /// - Parameter path: Path to the file where it should be written. /// - Parameter override: if project should be overridden. Default is false. @@ -141,12 +140,12 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { let encoder = getEncoder() try encoder.encode(self).write(to: path.url) } - + /// Gets the data representation of the property list representation of the object. /// /// - Throws: Error if encoding fails. public func dataRepresentation() throws -> Data? { - return try getEncoder().encode(self) + try getEncoder().encode(self) } private func getEncoder() -> PropertyListEncoder { @@ -160,35 +159,35 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { public init(from decoder: Decoder) throws { let plistDecoder = XcodeprojPropertyListDecoder() let container = try decoder.container(keyedBy: CodingKeys.self) - self.suppressBuildableAutocreation = try container.decodeIfPresent(.suppressBuildableAutocreation) + suppressBuildableAutocreation = try container.decodeIfPresent(.suppressBuildableAutocreation) if let schemeUserStateDictionary = try container.decodeIfPresent([String: Any].self, forKey: .schemeUserState) { - self.schemeUserState = try schemeUserStateDictionary + schemeUserState = try schemeUserStateDictionary .sorted(by: { $0.key < $1.key }) - .compactMap({ (key, value) -> XCSchemeManagement.UserStateScheme? in - var name = key - guard var valueDictionary = value as? [String: Any] else { return nil } - if key.contains("_^#shared#^_") { - valueDictionary["shared"] = true - name = key.replacingOccurrences(of: "_^#shared#^_", with: "") + .compactMap { key, value -> XCSchemeManagement.UserStateScheme? in + var name = key + guard var valueDictionary = value as? [String: Any] else { return nil } + if key.contains("_^#shared#^_") { + valueDictionary["shared"] = true + name = key.replacingOccurrences(of: "_^#shared#^_", with: "") + } + valueDictionary["name"] = name + + let data = try PropertyListSerialization.data(fromPropertyList: valueDictionary, format: .xml, options: 0) + return try plistDecoder.decode(XCSchemeManagement.UserStateScheme.self, from: data) } - valueDictionary["name"] = name - - let data = try PropertyListSerialization.data(fromPropertyList: valueDictionary, format: .xml, options: 0) - return try plistDecoder.decode(XCSchemeManagement.UserStateScheme.self, from: data) - }) } else { - self.suppressBuildableAutocreation = nil + suppressBuildableAutocreation = nil } } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - - if let suppressBuildableAutocreation = suppressBuildableAutocreation { + + if let suppressBuildableAutocreation { try container.encode(suppressBuildableAutocreation, forKey: .suppressBuildableAutocreation) } - - if let schemeUserState = schemeUserState { + + if let schemeUserState { let encodableSchemeUserState = schemeUserState .reduce(into: [String: XCSchemeManagement.UserStateScheme]()) { $0[$1.key] = $1 } try container.encode(encodableSchemeUserState, forKey: .schemeUserState) diff --git a/Sources/XcodeProj/Utils/BuildSettingsProvider.swift b/Sources/XcodeProj/Utils/BuildSettingsProvider.swift index 574f50ca..82a845c3 100644 --- a/Sources/XcodeProj/Utils/BuildSettingsProvider.swift +++ b/Sources/XcodeProj/Utils/BuildSettingsProvider.swift @@ -48,31 +48,31 @@ public class BuildSettingsProvider { public static func targetDefault(variant: Variant? = nil, platform: Platform?, product: Product?, swift: Bool? = nil) -> BuildSettings { var buildSettings: [String: Any] = [:] - if let platform = platform { + if let platform { buildSettings.merge(targetSettings(platform: platform), uniquingKeysWith: { $1 }) } - if let product = product { + if let product { buildSettings.merge(targetSettings(product: product), uniquingKeysWith: { $1 }) } - if let platform = platform, let product = product { + if let platform, let product { buildSettings.merge(targetSettings(platform: platform, product: product), uniquingKeysWith: { $1 }) } - if let platform = platform, let variant = variant { + if let platform, let variant { buildSettings.merge(targetSettings(variant: variant, platform: platform), uniquingKeysWith: { $1 }) } - if let variant = variant, let swift = swift, swift == true { + if let variant, let swift, swift == true { buildSettings.merge(targetSwiftSettings(variant: variant), uniquingKeysWith: { $1 }) } - if let product = product, let swift = swift, swift == true { + if let product, let swift, swift == true { buildSettings.merge(targetSwiftSettings(product: product), uniquingKeysWith: { $1 }) } - if let platform = platform, let product = product, let swift = swift, swift == true { + if let platform, let product, let swift, swift == true { buildSettings.merge(targetSwiftSettings(platform: platform, product: product), uniquingKeysWith: { $1 }) } diff --git a/Sources/XcodeProj/Utils/CommentedString.swift b/Sources/XcodeProj/Utils/CommentedString.swift index d543d975..2420f8e0 100644 --- a/Sources/XcodeProj/Utils/CommentedString.swift +++ b/Sources/XcodeProj/Utils/CommentedString.swift @@ -43,7 +43,7 @@ struct CommentedString { if string.rangeOfCharacter(from: CommentedString.invalidCharacters) == nil { if string.rangeOfCharacter(from: CommentedString.specialCheckCharacters) == nil { return string - } else if !string.contains("//") && !string.contains("___") { + } else if !string.contains("//"), !string.contains("___") { return string } } diff --git a/Sources/XcodeProj/Utils/Decoders.swift b/Sources/XcodeProj/Utils/Decoders.swift index f298d1d5..1bf6522c 100644 --- a/Sources/XcodeProj/Utils/Decoders.swift +++ b/Sources/XcodeProj/Utils/Decoders.swift @@ -44,7 +44,7 @@ class ProjectDecodingContext { extension CodingUserInfoKey { /// Context user info key. - static let context: CodingUserInfoKey = CodingUserInfoKey(rawValue: "context")! + static let context: CodingUserInfoKey = .init(rawValue: "context")! } /// Xcodeproj JSON decoder. diff --git a/Sources/XcodeProj/Utils/JSONDecoding.swift b/Sources/XcodeProj/Utils/JSONDecoding.swift index ac331169..2e80a607 100644 --- a/Sources/XcodeProj/Utils/JSONDecoding.swift +++ b/Sources/XcodeProj/Utils/JSONDecoding.swift @@ -21,8 +21,8 @@ extension KeyedDecodingContainer { func decode(_ type: [String: Any].Type, forKey key: K) throws -> [String: Any] { // Optimization for root dictionary decoding if let decoder = try? superDecoder().context, - let pbxProjValueReader = decoder.pbxProjValueReader, - let result = pbxProjValueReader(key.stringValue) as? [String: Any] { + let pbxProjValueReader = decoder.pbxProjValueReader, + let result = pbxProjValueReader(key.stringValue) as? [String: Any] { return result } let container = try nestedContainer(keyedBy: JSONCodingKeys.self, forKey: key) @@ -95,7 +95,7 @@ extension UnkeyedDecodingContainer { } mutating func decode(_ type: [String: Any].Type) throws -> [String: Any] { - let nestedContainer = try self.nestedContainer(keyedBy: JSONCodingKeys.self) + let nestedContainer = try nestedContainer(keyedBy: JSONCodingKeys.self) return try nestedContainer.decode(type) } } diff --git a/Sources/XcodeProj/Utils/PBXBatchUpdater.swift b/Sources/XcodeProj/Utils/PBXBatchUpdater.swift index a00d30c5..d23a4926 100644 --- a/Sources/XcodeProj/Utils/PBXBatchUpdater.swift +++ b/Sources/XcodeProj/Utils/PBXBatchUpdater.swift @@ -28,17 +28,17 @@ public final class PBXBatchUpdater { sourceTree: PBXSourceTree = .group ) throws -> PBXFileReference { - let (group, groupPath) = try groupAndGroupPathForFile( - at: filePath, - project: project - ) - return try addFile( - to: group, - groupPath: groupPath, - filePath: filePath, - sourceTree: sourceTree - ) - } + let (group, groupPath) = try groupAndGroupPathForFile( + at: filePath, + project: project + ) + return try addFile( + to: group, + groupPath: groupPath, + filePath: filePath, + sourceTree: sourceTree + ) + } /// Adds file at the give path to the project or returns existing file and its reference. /// @@ -54,15 +54,15 @@ public final class PBXBatchUpdater { sourceTree: PBXSourceTree = .group ) throws -> PBXFileReference { - let groupPath = try group.fullPath(sourceRoot: sourceRoot)! - let filePath = groupPath + Path(fileName) - return try addFile( - to: group, - groupPath: groupPath, - filePath: filePath, - sourceTree: sourceTree - ) - } + let groupPath = try group.fullPath(sourceRoot: sourceRoot)! + let filePath = groupPath + Path(fileName) + return try addFile( + to: group, + groupPath: groupPath, + filePath: filePath, + sourceTree: sourceTree + ) + } private func addFile( to group: PBXGroup, @@ -71,41 +71,41 @@ public final class PBXBatchUpdater { sourceTree: PBXSourceTree = .group ) throws -> PBXFileReference { - if let existing = try existingFileReference(at: filePath, in: group) { - return existing - } + if let existing = try existingFileReference(at: filePath, in: group) { + return existing + } - let path: String? - switch sourceTree { - case .group: - path = filePath.relative(to: groupPath).string - case .sourceRoot: - path = filePath.relative(to: sourceRoot).string - case .absolute: - path = filePath.string - default: - path = nil - } - let fileReference = PBXFileReference( - sourceTree: sourceTree, - name: filePath.lastComponent, - explicitFileType: filePath.extension.flatMap(Xcode.filetype), - lastKnownFileType: filePath.extension.flatMap(Xcode.filetype), - path: path - ) - objects.add(object: fileReference) - fileReference.parent = group - references?[filePath] = fileReference.reference - if !group.childrenReferences.contains(fileReference.reference) { - group.childrenReferences.append(fileReference.reference) - } - return fileReference + let path: String? + switch sourceTree { + case .group: + path = filePath.relative(to: groupPath).string + case .sourceRoot: + path = filePath.relative(to: sourceRoot).string + case .absolute: + path = filePath.string + default: + path = nil + } + let fileReference = PBXFileReference( + sourceTree: sourceTree, + name: filePath.lastComponent, + explicitFileType: filePath.extension.flatMap(Xcode.filetype), + lastKnownFileType: filePath.extension.flatMap(Xcode.filetype), + path: path + ) + objects.add(object: fileReference) + fileReference.parent = group + references?[filePath] = fileReference.reference + if !group.childrenReferences.contains(fileReference.reference) { + group.childrenReferences.append(fileReference.reference) } + return fileReference + } private func existingFileReference(at filePath: Path, in group: PBXGroup) throws -> PBXFileReference? { let objectReferences = try lazilyInstantiateObjectReferences() if let existingObjectReference = objectReferences[filePath], - let existingFileReference = objects.fileReferences[existingObjectReference] { + let existingFileReference = objects.fileReferences[existingObjectReference] { if !group.childrenReferences.contains(existingObjectReference) { group.childrenReferences.append(existingObjectReference) } @@ -155,23 +155,23 @@ public final class PBXBatchUpdater { with names: [String] ) throws -> PBXGroup { - var parent = group - for (index, name) in names.enumerated() { - let path = groupPath + Path(components: names[0 ... index]) - parent = try parent.addGroup(named: name).last! - groups?[path] = parent - } - return parent + var parent = group + for (index, name) in names.enumerated() { + let path = groupPath + Path(components: names[0 ... index]) + parent = try parent.addGroup(named: name).last! + groups?[path] = parent } + return parent + } private func lazilyInstantiateObjectReferences() throws -> [Path: PBXObjectReference] { let objectReferences: [Path: PBXObjectReference] - if let references = self.references { + if let references { objectReferences = references } else { - objectReferences = Dictionary(uniqueKeysWithValues: - try objects.fileReferences.compactMap { + objectReferences = try Dictionary(uniqueKeysWithValues: + objects.fileReferences.compactMap { let fullPath = try $0.value.fullPath(sourceRoot: sourceRoot)! return (fullPath, $0.key) }) @@ -182,11 +182,11 @@ public final class PBXBatchUpdater { private func lazilyInstantiateGroups() throws -> [Path: PBXGroup] { let unwrappedGroups: [Path: PBXGroup] - if let groups = self.groups { + if let groups { unwrappedGroups = groups } else { - unwrappedGroups = Dictionary(uniqueKeysWithValues: - try objects.groups.compactMap { + unwrappedGroups = try Dictionary(uniqueKeysWithValues: + objects.groups.compactMap { let fullPath = try $0.value.fullPath(sourceRoot: sourceRoot)! return (fullPath, $0.value) }) diff --git a/Sources/XcodeProj/Utils/PlistValue.swift b/Sources/XcodeProj/Utils/PlistValue.swift index abd99a51..d36496c5 100644 --- a/Sources/XcodeProj/Utils/PlistValue.swift +++ b/Sources/XcodeProj/Utils/PlistValue.swift @@ -105,7 +105,7 @@ extension Dictionary where Key == String { extension Array { func plist() -> PlistValue { - .array(compactMap { (element) -> PlistValue? in + .array(compactMap { element -> PlistValue? in if let array = element as? [Any] { return array.plist() } else if let dictionary = element as? [String: Any] { diff --git a/Sources/XcodeProj/Utils/ReferenceGenerator.swift b/Sources/XcodeProj/Utils/ReferenceGenerator.swift index e4a5f3da..823c582b 100644 --- a/Sources/XcodeProj/Utils/ReferenceGenerator.swift +++ b/Sources/XcodeProj/Utils/ReferenceGenerator.swift @@ -31,6 +31,7 @@ final class ReferenceGenerator: ReferenceGenerating { // cache current reference values var references: Set = [] + // swiftformat:disable:next preferForLoop proj.objects.forEach { object in if !object.reference.temporary { references.insert(object.reference.value) @@ -53,7 +54,7 @@ final class ReferenceGenerator: ReferenceGenerating { // Project references try project.projectReferences.forEach { objectReferenceDict in guard let projectReference = objectReferenceDict[Xcode.ProjectReference.projectReferenceKey]?.getObject() as? PBXFileReference, - let productsGroup = objectReferenceDict[Xcode.ProjectReference.productGroupKey]?.getObject() as? PBXGroup else { return } + let productsGroup = objectReferenceDict[Xcode.ProjectReference.productGroupKey]?.getObject() as? PBXGroup else { return } try generateFileReference(projectReference, identifiers: identifiers) try generateGroupReferences(productsGroup, identifiers: identifiers + [projectReference.name ?? projectReference.path ?? ""]) } @@ -79,31 +80,30 @@ final class ReferenceGenerator: ReferenceGenerating { fixReference(for: project, identifiers: identifiers) // Packages - project.remotePackages.forEach { + for remotePackage in project.remotePackages { var identifiers = identifiers - identifiers.append($0.repositoryURL ?? $0.name ?? "") - fixReference(for: $0, identifiers: identifiers) + identifiers.append(remotePackage.repositoryURL ?? remotePackage.name ?? "") + fixReference(for: remotePackage, identifiers: identifiers) } // Packages - project.localPackages.forEach { + for localPackage in project.localPackages { var identifiers = identifiers - identifiers.append($0.relativePath) - fixReference(for: $0, identifiers: identifiers) + identifiers.append(localPackage.relativePath) + fixReference(for: localPackage, identifiers: identifiers) } // Targets let targets: [PBXTarget] = project.targetReferences.objects() - targets.forEach { target in - + for target in targets { var identifiers = identifiers identifiers.append(target.name) // Packages - target.packageProductDependencies.forEach { + for packageProductDependency in target.packageProductDependencies { var identifiers = identifiers - identifiers.append($0.productName) - fixReference(for: $0, identifiers: identifiers) + identifiers.append(packageProductDependency.productName) + fixReference(for: packageProductDependency, identifiers: identifiers) } // Build Tool Plug-ins @@ -223,9 +223,9 @@ final class ReferenceGenerator: ReferenceGenerating { // Target proxy if let targetProxyReference = targetDependency.targetProxyReference, - targetProxyReference.temporary, - let targetProxy = targetDependency.targetProxy, - let remoteGlobalIDString = targetProxy.remoteGlobalID?.uuid { + targetProxyReference.temporary, + let targetProxy = targetDependency.targetProxy, + let remoteGlobalIDString = targetProxy.remoteGlobalID?.uuid { var identifiers = identifiers identifiers.append(remoteGlobalIDString) fixReference(for: targetProxy, identifiers: identifiers) @@ -302,7 +302,7 @@ final class ReferenceGenerator: ReferenceGenerating { var identifiers = identifiers if let fileReference = buildFile.fileReference, - let fileReferenceObject: PBXObject = fileReference.getObject() { + let fileReferenceObject: PBXObject = fileReference.getObject() { identifiers.append(fileReferenceObject.reference.value) } @@ -333,8 +333,8 @@ extension ReferenceGenerator { /// - Parameters: /// - object: The object to generate a reference for /// - identifiers: list of identifiers used to generate the reference of the object. - func fixReference(for object: T, - identifiers: [String]) { + func fixReference(for object: some PBXObject, + identifiers: [String]) { if object.reference.temporary { var identifiers = identifiers if let context = object.context { diff --git a/Sources/XcodeProj/Utils/XCConfig.swift b/Sources/XcodeProj/Utils/XCConfig.swift index 7f7a119a..e1e585ea 100644 --- a/Sources/XcodeProj/Utils/XCConfig.swift +++ b/Sources/XcodeProj/Utils/XCConfig.swift @@ -43,7 +43,7 @@ public final class XCConfig { } } -final class XCConfigParser { +enum XCConfigParser { /// Given the path the line is being parsed from, it returns a function that parses a line, /// and returns the include path and the config that the include is pointing to. /// @@ -56,19 +56,19 @@ final class XCConfigParser { options: [], range: NSRange(location: 0, length: line.count)) - .compactMap { (match) -> String? in + .compactMap { match -> String? in if match.numberOfRanges == 2 { return NSString(string: line).substring(with: match.range(at: 1)) } return nil } .compactMap { pathString in - let includePath: Path = Path(pathString) + let includePath: Path = .init(pathString) var config: XCConfig? do { // first try to load the included xcconfig relative to the current xcconfig config = try XCConfig(path: path.parent() + includePath, projectPath: projectPath) - } catch (XCConfigError.notFound(_)) where projectPath != nil { + } catch XCConfigError.notFound(_) where projectPath != nil { // if that fails, try to load the included xcconfig relative to the project config = try? XCConfig(path: projectPath!.parent() + includePath, projectPath: projectPath) } catch { @@ -85,7 +85,7 @@ final class XCConfigParser { options: [], range: NSRange(location: 0, length: line.count)) - .compactMap { (match) -> (key: String, value: String)? in + .compactMap { match -> (key: String, value: String)? in if match.numberOfRanges == 3 { let key: String = NSString(string: line).substring(with: match.range(at: 1)) let value: String = NSString(string: line).substring(with: match.range(at: 2)) @@ -120,18 +120,18 @@ extension XCConfig: Equatable { // MARK: - XCConfig Extension (Helpers) -extension XCConfig { +public extension XCConfig { /// It returns the build settings after flattening all the includes. /// /// - Returns: build settings flattening all the includes. - public func flattenedBuildSettings() -> [String: Any] { + func flattenedBuildSettings() -> [String: Any] { var content: [String: Any] = buildSettings includes - .map { $0.1 } + .map(\.1) .flattened() - .map { $0.buildSettings } + .map(\.buildSettings) .forEach { configDictionary in - configDictionary.forEach { key, value in + for (key, value) in configDictionary { if content[key] == nil { content[key] = value } } } @@ -149,11 +149,11 @@ extension XCConfig: Writable { } try path.write(content) } - + public func dataRepresentation() throws -> Data? { getContent().data(using: .utf8) } - + private func getContent() -> String { var content = "" content.append(writeIncludes()) @@ -164,7 +164,7 @@ extension XCConfig: Writable { private func writeIncludes() -> String { var content = "" - includes.forEach { include in + for include in includes { content.append("#include \"\(include.0.string)\"\n") } content.append("\n") @@ -173,7 +173,7 @@ extension XCConfig: Writable { private func writeBuildSettings() -> String { var content = "" - buildSettings.forEach { key, value in + for (key, value) in buildSettings { content.append("\(key) = \(value)\n") } content.append("\n") @@ -183,15 +183,15 @@ extension XCConfig: Writable { // MARK: - Array Extension (XCConfig) -extension Array where Element == XCConfig { +extension [XCConfig] { /// It returns an array with the XCConfig reversely flattened. It's useful for resolving the build settings. /// /// - Returns: flattened configurations array. func flattened() -> [XCConfig] { - let reversed = self.reversed() - .flatMap { (config) -> [XCConfig] in + let reversed = reversed() + .flatMap { config -> [XCConfig] in var configs = [XCConfig(includes: [], buildSettings: config.buildSettings)] - configs.append(contentsOf: config.includes.map { $0.1 }.flattened()) + configs.append(contentsOf: config.includes.map(\.1).flattened()) return configs } return reversed diff --git a/Sources/XcodeProj/Workspace/XCWorkspace.swift b/Sources/XcodeProj/Workspace/XCWorkspace.swift index 4707d930..7f99f6c0 100644 --- a/Sources/XcodeProj/Workspace/XCWorkspace.swift +++ b/Sources/XcodeProj/Workspace/XCWorkspace.swift @@ -67,9 +67,9 @@ public final class XCWorkspace: Writable, Equatable { try dataPath.mkpath() try data.write(path: dataPath) } - + public func dataRepresentation() throws -> Data? { - self.data.rawContents().data(using: .utf8) + data.rawContents().data(using: .utf8) } // MARK: - Equatable diff --git a/Sources/XcodeProj/Workspace/XCWorkspaceData.swift b/Sources/XcodeProj/Workspace/XCWorkspaceData.swift index 9cd95c7c..13c413bb 100644 --- a/Sources/XcodeProj/Workspace/XCWorkspaceData.swift +++ b/Sources/XcodeProj/Workspace/XCWorkspaceData.swift @@ -36,7 +36,7 @@ extension XCWorkspaceData: Writable { self.init(children: children) } - + func rawContents() -> String { let document = AEXMLDocument() let workspace = document.addChild(name: "Workspace", value: nil, attributes: ["version": "1.0"]) @@ -47,7 +47,7 @@ extension XCWorkspaceData: Writable { } // MARK: - - + public func write(path: Path, override: Bool = true) throws { let rawXml = rawContents() if override, path.exists { @@ -55,7 +55,7 @@ extension XCWorkspaceData: Writable { } try path.write(rawXml) } - + public func dataRepresentation() throws -> Data? { rawContents().data(using: .utf8) } @@ -134,7 +134,7 @@ private extension XCWorkspaceDataFileRef { guard let location = element.attributes["location"] else { throw Error.missingLocationAttribute } - self.init(location: try XCWorkspaceDataElementLocationType(string: location)) + try self.init(location: XCWorkspaceDataElementLocationType(string: location)) } func xmlElement() -> AEXMLElement { diff --git a/Tests/XcodeProjTests/Extensions/AEXML+XcodeFormatTests.swift b/Tests/XcodeProjTests/Extensions/AEXML+XcodeFormatTests.swift index bbae0766..d7836dff 100644 --- a/Tests/XcodeProjTests/Extensions/AEXML+XcodeFormatTests.swift +++ b/Tests/XcodeProjTests/Extensions/AEXML+XcodeFormatTests.swift @@ -123,7 +123,7 @@ class AEXML_XcodeFormatTests: XCTestCase { "buildConfiguration": "Debug", "selectedLauncherIdentifier": "Xcode.DebuggerFoundation.Launcher.LLDB", "launchStyle": "0", - "askForAppToLaunch": "YES" + "askForAppToLaunch": "YES", ] ) } @@ -151,7 +151,7 @@ class AEXML_XcodeFormatTests: XCTestCase { "shouldUseLaunchSchemeArgsEnv": "YES", "buildConfiguration": "Debug", "customLLDBInitFile": "$(BAZEL_LLDB_INIT)", - "selectedLauncherIdentifier": "Xcode.DebuggerFoundation.Launcher.LLDB" + "selectedLauncherIdentifier": "Xcode.DebuggerFoundation.Launcher.LLDB", ] ) } @@ -163,7 +163,7 @@ class AEXML_XcodeFormatTests: XCTestCase { attributes: [ "LastUpgradeVersion": "1320", "wasCreatedForAppExtension": "YES", - "version": "1.7" + "version": "1.7", ] ) } @@ -175,7 +175,7 @@ class AEXML_XcodeFormatTests: XCTestCase { attributes: [ "wasCreatedForAppExtension": "YES", "LastUpgradeVersion": "1320", - "version": "1.7" + "version": "1.7", ] ) } @@ -187,7 +187,7 @@ class AEXML_XcodeFormatTests: XCTestCase { attributes: [ "BundleIdentifier": "BundleID", "RemotePath": "REMOTE_PATH", - "runnableDebuggingMode": "2" + "runnableDebuggingMode": "2", ] ) } diff --git a/Tests/XcodeProjTests/Extensions/XCTestCase+Assertions.swift b/Tests/XcodeProjTests/Extensions/XCTestCase+Assertions.swift index 67df9c18..9d1330dd 100644 --- a/Tests/XcodeProjTests/Extensions/XCTestCase+Assertions.swift +++ b/Tests/XcodeProjTests/Extensions/XCTestCase+Assertions.swift @@ -2,7 +2,7 @@ import Foundation import XCTest extension XCTestCase { - typealias EquatableError = Error & Equatable + typealias EquatableError = Equatable & Error func XCTAssertNotNilAndUnwrap(_ obj: T?, message: String = "") -> T { guard let unwrappedObj = obj else { @@ -12,7 +12,7 @@ extension XCTestCase { return unwrappedObj } - func XCTAssertThrowsSpecificError(_ expression: @autoclosure () throws -> T, _ error: E, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { + func XCTAssertThrowsSpecificError(_ expression: @autoclosure () throws -> some Any, _ error: E, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { XCTAssertThrowsError(try expression(), message(), file: file, line: line) { actualError in let message = "Expected \(error) got \(actualError)" diff --git a/Tests/XcodeProjTests/Objects/BuildPhase/PBXBuildFileTests.swift b/Tests/XcodeProjTests/Objects/BuildPhase/PBXBuildFileTests.swift index 517dad19..5dbd1cd2 100644 --- a/Tests/XcodeProjTests/Objects/BuildPhase/PBXBuildFileTests.swift +++ b/Tests/XcodeProjTests/Objects/BuildPhase/PBXBuildFileTests.swift @@ -8,7 +8,7 @@ final class PBXBuildFileTests: XCTestCase { } func test_platformFilterIsSet() { - let pbxBuildFile: PBXBuildFile = PBXBuildFile( + let pbxBuildFile = PBXBuildFile( platformFilter: "platformFilter" ) XCTAssertEqual(pbxBuildFile.platformFilter, "platformFilter") diff --git a/Tests/XcodeProjTests/Objects/BuildPhase/PBXShellScriptBuildPhaseTests.swift b/Tests/XcodeProjTests/Objects/BuildPhase/PBXShellScriptBuildPhaseTests.swift index 86692b49..18de54b2 100644 --- a/Tests/XcodeProjTests/Objects/BuildPhase/PBXShellScriptBuildPhaseTests.swift +++ b/Tests/XcodeProjTests/Objects/BuildPhase/PBXShellScriptBuildPhaseTests.swift @@ -16,7 +16,8 @@ final class PBXShellScriptBuildPhaseTests: XCTestCase { let (_, doNotShowPlistValue) = try doNotShow.plistKeyAndValue(proj: proj, reference: "ref") if case let PlistValue.dictionary(showDictionary) = showPlistValue, - case let PlistValue.dictionary(doNotShowDictionary) = doNotShowPlistValue { + case let PlistValue.dictionary(doNotShowDictionary) = doNotShowPlistValue + { XCTAssertNil(showDictionary["showEnvVarsInLog"]) XCTAssertEqual(doNotShowDictionary["showEnvVarsInLog"]?.string, "0") } else { @@ -35,7 +36,8 @@ final class PBXShellScriptBuildPhaseTests: XCTestCase { guard case let .dictionary(valuesWhenNotPresent) = try alwaysOutOfDateNotPresent.plistKeyAndValue(proj: proj, reference: "ref").value, case let .dictionary(valuesWhenFalse) = try alwaysOutOfDateFalse.plistKeyAndValue(proj: proj, reference: "ref").value, - case let .dictionary(valuesWhenTrue) = try alwaysOutOfDateTrue.plistKeyAndValue(proj: proj, reference: "ref").value else { + case let .dictionary(valuesWhenTrue) = try alwaysOutOfDateTrue.plistKeyAndValue(proj: proj, reference: "ref").value + else { XCTFail("Plist should contain dictionary") return } @@ -45,7 +47,7 @@ final class PBXShellScriptBuildPhaseTests: XCTestCase { XCTAssertFalse(valuesWhenFalse.keys.contains("alwaysOutOfDate")) XCTAssertEqual(valuesWhenTrue["alwaysOutOfDate"], "1") } - + func test_write_dependencyFile() throws { let discoveryPath = "$(DERIVED_FILE_DIR)/target.d" let discovery = PBXShellScriptBuildPhase(dependencyFile: discoveryPath) diff --git a/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationList+Fixtures.swift b/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationList+Fixtures.swift index f3b6e28e..975838b0 100644 --- a/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationList+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationList+Fixtures.swift @@ -5,7 +5,8 @@ extension XCConfigurationList { static func fixture(buildConfigurations: [XCBuildConfiguration] = [XCBuildConfiguration.fixture(name: "Debug"), XCBuildConfiguration.fixture(name: "Release")], defaultConfigurationName: String? = "Debug", - defaultConfigurationIsVisible _: Bool = true) -> XCConfigurationList { + defaultConfigurationIsVisible _: Bool = true) -> XCConfigurationList + { XCConfigurationList(buildConfigurations: buildConfigurations, defaultConfigurationName: defaultConfigurationName) } diff --git a/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationListTests.swift b/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationListTests.swift index 447ed7e5..1a382450 100644 --- a/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationListTests.swift +++ b/Tests/XcodeProjTests/Objects/Configuration/XCConfigurationListTests.swift @@ -12,7 +12,7 @@ final class XCConfigurationListTests: XCTestCase { let configurationList = XCConfigurationList(buildConfigurations: []) objects.add(object: configurationList) let configurations = try configurationList.addDefaultConfigurations() - let names = configurations.map { $0.name } + let names = configurations.map(\.name) XCTAssertEqual(configurations.count, 2) XCTAssertTrue(names.contains("Debug")) diff --git a/Tests/XcodeProjTests/Objects/Files/PBXFileReference+Fixtures.swift b/Tests/XcodeProjTests/Objects/Files/PBXFileReference+Fixtures.swift index 042d56e1..58c65087 100644 --- a/Tests/XcodeProjTests/Objects/Files/PBXFileReference+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Files/PBXFileReference+Fixtures.swift @@ -4,7 +4,8 @@ import Foundation extension PBXFileReference { static func fixture(sourceTree _: PBXSourceTree = .group, - name: String? = "Test") -> PBXFileReference { + name: String? = "Test") -> PBXFileReference + { PBXFileReference(sourceTree: .group, name: name) } } diff --git a/Tests/XcodeProjTests/Objects/Files/PBXGroup+Fixtures.swift b/Tests/XcodeProjTests/Objects/Files/PBXGroup+Fixtures.swift index 0f95e2b4..fb617bd0 100644 --- a/Tests/XcodeProjTests/Objects/Files/PBXGroup+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Files/PBXGroup+Fixtures.swift @@ -4,7 +4,8 @@ import Foundation extension PBXGroup { static func fixture(children _: [PBXFileElement] = [], sourceTree: PBXSourceTree = .group, - name: String = "test") -> PBXGroup { + name: String = "test") -> PBXGroup + { PBXGroup(children: [], sourceTree: sourceTree, name: name) diff --git a/Tests/XcodeProjTests/Objects/Files/PBXGroupTests.swift b/Tests/XcodeProjTests/Objects/Files/PBXGroupTests.swift index 6fd5360d..915a714d 100644 --- a/Tests/XcodeProjTests/Objects/Files/PBXGroupTests.swift +++ b/Tests/XcodeProjTests/Objects/Files/PBXGroupTests.swift @@ -71,7 +71,7 @@ final class PBXGroupTests: XCTestCase { XCTAssertEqual(childVariantGroups.count, expectedGroupNames.count) - childVariantGroups.enumerated().forEach { index, variantGroup in + for (index, variantGroup) in childVariantGroups.enumerated() { let parentGroup = (index == 0) ? group : childVariantGroups[index - 1] if index == childVariantGroups.count - 1 { diff --git a/Tests/XcodeProjTests/Objects/Files/XCVersionGroup+Fixtures.swift b/Tests/XcodeProjTests/Objects/Files/XCVersionGroup+Fixtures.swift index 604c1a27..310a5da4 100644 --- a/Tests/XcodeProjTests/Objects/Files/XCVersionGroup+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Files/XCVersionGroup+Fixtures.swift @@ -8,14 +8,15 @@ extension XCVersionGroup { name: String? = "name", sourceTree: PBXSourceTree = .group, versionGroupType: String = "versionGroupType", - children: [PBXFileReference] = [PBXFileReference(name: "currentVersion")]) -> XCVersionGroup { + children: [PBXFileReference] = [PBXFileReference(name: "currentVersion")]) -> XCVersionGroup + { let group = XCVersionGroup(currentVersion: currentVersion, path: path, name: name, sourceTree: sourceTree, versionGroupType: versionGroupType, children: children) - if let currentVersion = currentVersion { + if let currentVersion { objects.add(object: currentVersion) } children.forEach { objects.add(object: $0) } diff --git a/Tests/XcodeProjTests/Objects/Project/PBXOutputSettingsTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXOutputSettingsTests.swift index 33c5fc8f..03fbc022 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXOutputSettingsTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXOutputSettingsTests.swift @@ -6,28 +6,28 @@ class PBXOutputSettingsTests: XCTestCase { // MARK: - PBXFileOrder - PBXBuldFile func test_PBXFileOrder_PBXBuildFile_by_uuid_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertFalse(PBXFileOrder.byUUID.sort(lhs: iosProject.objectBuildFileAssets, rhs: iosProject.objectBuildFileMain)) XCTAssertTrue(PBXFileOrder.byUUID.sort(lhs: iosProject.objectBuildFileMain, rhs: iosProject.objectBuildFileAssets)) } func test_PBXFileOrder_PBXBuildFile_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXFileOrder.byFilename.sort(lhs: iosProject.objectBuildFileAssets, rhs: iosProject.objectBuildFileMain)) XCTAssertFalse(PBXFileOrder.byFilename.sort(lhs: iosProject.objectBuildFileMain, rhs: iosProject.objectBuildFileAssets)) } func test_PBXFileOrder_PBXBuildFile_by_filename_when_fileSharedAcrossTargetsProject() { - let fileSharedAcrossTargetsProject = self.fileSharedAcrossTargetsProject() + let fileSharedAcrossTargetsProject = fileSharedAcrossTargetsProject() let sameNameByFilename = fileSharedAcrossTargetsProject.objectBuildFileSameName.sorted(by: PBXFileOrder.byFilename.sort) XCTAssertLessThan(sameNameByFilename.first!.1.uuid, sameNameByFilename.last!.1.uuid) } func test_PBXFileOrder_PBXBuildFile_by_filename_when_nil_name_and_path_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() iosProject.buildFileAssets.file?.name = nil iosProject.buildFileMain.file?.name = nil @@ -38,7 +38,7 @@ class PBXOutputSettingsTests: XCTestCase { } func test_PBXFileOrder_PBXBuildFile_by_filename_when_no_file_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() let ref1 = iosProject.buildFileAssets.reference let ref2 = iosProject.buildFileMain.reference @@ -51,14 +51,14 @@ class PBXOutputSettingsTests: XCTestCase { // MARK: - PBXFileOrder - PBXBuildPhaseFile func test_PBXFileOrder_PBXBuildPhaseFile_by_uuid_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertFalse(PBXFileOrder.byUUID.sort(lhs: iosProject.objectBuildPhaseFileAssets, rhs: iosProject.objectBuildPhaseFileMain)) XCTAssertTrue(PBXFileOrder.byUUID.sort(lhs: iosProject.objectBuildPhaseFileMain, rhs: iosProject.objectBuildPhaseFileAssets)) } func test_PBXFileOrder_PBXBuildPhaseFile_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXFileOrder.byFilename.sort(lhs: iosProject.objectBuildPhaseFileAssets, rhs: iosProject.objectBuildPhaseFileMain)) XCTAssertFalse(PBXFileOrder.byFilename.sort(lhs: iosProject.objectBuildPhaseFileMain, rhs: iosProject.objectBuildPhaseFileAssets)) @@ -67,28 +67,28 @@ class PBXOutputSettingsTests: XCTestCase { // MARK: - PBXFileOrder - PBXFileReference func test_PBXFileOrder_PBXFileReference_by_uuid_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertFalse(PBXFileOrder.byUUID.sort(lhs: iosProject.objectFileReferenceAssets, rhs: iosProject.objectFileReferenceCoreData)) XCTAssertTrue(PBXFileOrder.byUUID.sort(lhs: iosProject.objectFileReferenceCoreData, rhs: iosProject.objectFileReferenceAssets)) } func test_PBXFileOrder_PBXFileReference_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXFileOrder.byFilename.sort(lhs: iosProject.objectFileReferenceAssets, rhs: iosProject.objectFileReferenceCoreData)) XCTAssertFalse(PBXFileOrder.byFilename.sort(lhs: iosProject.objectFileReferenceCoreData, rhs: iosProject.objectFileReferenceAssets)) } func test_PBXFileOrder_PBXFileReference_by_filename_when_fileSharedAcrossTargetsProject() { - let fileSharedAcrossTargetsProject = self.fileSharedAcrossTargetsProject() + let fileSharedAcrossTargetsProject = fileSharedAcrossTargetsProject() let sameNameByFilename = fileSharedAcrossTargetsProject.objectFileReferenceSameName.sorted(by: PBXFileOrder.byFilename.sort) XCTAssertLessThan(sameNameByFilename.first!.1.uuid, sameNameByFilename.last!.1.uuid) } func test_PBXFileOrder_PBXFileReference_by_filename_when_nil_name_and_path_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() iosProject.fileReferenceAssets.name = nil iosProject.fileReferenceCoreData.name = nil @@ -101,14 +101,14 @@ class PBXOutputSettingsTests: XCTestCase { // MARK: - PBXFileOrder - Other func test_PBXFileOrder_Other_by_uuid_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXFileOrder.byUUID.sort(lhs: iosProject.objectGroupFrameworks, rhs: iosProject.objectGroupProducts)) XCTAssertFalse(PBXFileOrder.byUUID.sort(lhs: iosProject.objectGroupProducts, rhs: iosProject.objectGroupFrameworks)) } func test_PBXFileOrder_Other_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXFileOrder.byFilename.sort(lhs: iosProject.objectGroupFrameworks, rhs: iosProject.objectGroupProducts)) XCTAssertFalse(PBXFileOrder.byFilename.sort(lhs: iosProject.objectGroupProducts, rhs: iosProject.objectGroupFrameworks)) @@ -121,7 +121,7 @@ class PBXOutputSettingsTests: XCTestCase { } func test_PBXNavigatorFileOrder_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() let sort: (PBXFileElement, PBXFileElement) -> Bool = PBXNavigatorFileOrder.byFilename.sort! let sorted = iosProject.navigatorFileGroup.children.sorted(by: sort).map { $0.fileName()! } @@ -141,7 +141,7 @@ class PBXOutputSettingsTests: XCTestCase { } func test_PBXNavigatorFileOrder_by_filename_groups_first_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() let sort: (PBXFileElement, PBXFileElement) -> Bool = PBXNavigatorFileOrder.byFilenameGroupsFirst.sort! let sorted = iosProject.navigatorFileGroup.children.sorted(by: sort).map { $0.fileName()! } @@ -167,7 +167,7 @@ class PBXOutputSettingsTests: XCTestCase { } func test_PBXBuildPhaseFileOrder_by_filename_when_iosProject() { - let iosProject = self.iosProject() + let iosProject = iosProject() XCTAssertTrue(PBXBuildPhaseFileOrder.byFilename.sort!(iosProject.buildFileAssets, iosProject.buildFileMain)) XCTAssertFalse(PBXBuildPhaseFileOrder.byFilename.sort!(iosProject.buildFileMain, iosProject.buildFileAssets)) diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProj+Fixtures.swift b/Tests/XcodeProjTests/Objects/Project/PBXProj+Fixtures.swift index 8a397023..ade46a2a 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProj+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProj+Fixtures.swift @@ -6,7 +6,8 @@ extension PBXProj { objectVersion: UInt = Xcode.LastKnown.objectVersion, archiveVersion: UInt = Xcode.LastKnown.archiveVersion, classes: [String: Any] = [:], - objects: [PBXObject] = []) -> PBXProj { + objects: [PBXObject] = []) -> PBXProj + { PBXProj(rootObject: rootObject, objectVersion: objectVersion, archiveVersion: archiveVersion, diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift index e7ebb629..d60e0838 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift @@ -11,7 +11,7 @@ class PBXProjEncoderTests: XCTestCase { func test_writeHeaders_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) XCTAssertEqual(583, lines.count) XCTAssertEqual("// !$*UTF8*$!", lines[0]) } @@ -21,7 +21,7 @@ class PBXProjEncoderTests: XCTestCase { func test_buildFiles_in_default_uuid_order_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) var line = lines.validate(line: "/* Begin PBXBuildFile section */") line = lines.validate(lineContaining: "04D5C09F1F153824008A2F98 /* CoreData.framework in Frameworks */", onLineAfter: line) line = lines.validate(lineContaining: "04D5C0A31F153924008A2F98 /* Public.h in Headers */", onLineAfter: line) @@ -43,7 +43,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projFileListOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) var line = lines.validate(line: "/* Begin PBXBuildFile section */") line = lines.validate(lineContaining: "23766C161EAA3484007A9026 /* AppDelegate.swift in Sources */", onLineAfter: line) line = lines.validate(lineContaining: "23766C1D1EAA3484007A9026 /* Assets.xcassets in Resources */", onLineAfter: line) @@ -65,7 +65,7 @@ class PBXProjEncoderTests: XCTestCase { try loadFileSharedAcrossTargetsProject() let settings = PBXOutputSettings(projFileListOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) var line = lines.validate(line: "/* Begin PBXBuildFile section */") line = lines.validate(lineContaining: "6C103C032A49CC5400D7EFE4 /* FileSharedAcrossTargets.framework in Frameworks */", onLineAfter: line) @@ -79,7 +79,7 @@ class PBXProjEncoderTests: XCTestCase { func test_file_references_in_default_uuid_order_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) var line = lines.validate(line: "/* Begin PBXFileReference section */") line = lines.validate(lineContaining: "04D5C09E1F153824008A2F98 /* CoreData.framework */", onLineAfter: line) line = lines.validate(lineContaining: "04D5C0A01F153915008A2F98 /* Public.h */", onLineAfter: line) @@ -105,7 +105,7 @@ class PBXProjEncoderTests: XCTestCase { func test_file_references_in_default_uuid_order_when_fileSharedAcrossTargetsProject() throws { try loadFileSharedAcrossTargetsProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) var line = lines.validate(line: "/* Begin PBXFileReference section */") line = lines.validate(lineContaining: "6C103BFA2A49CC5300D7EFE4 /* FileSharedAcrossTargets.framework */", onLineAfter: line) line = lines.validate(lineContaining: "6C103BFD2A49CC5300D7EFE4 /* FileSharedAcrossTargets.h */", onLineAfter: line) @@ -121,7 +121,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projFileListOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) var line = lines.validate(line: "/* Begin PBXFileReference section */") line = lines.validate(lineContaining: "23766C151EAA3484007A9026 /* AppDelegate.swift */", onLineAfter: line) line = lines.validate(lineContaining: "23766C1C1EAA3484007A9026 /* Assets.xcassets */", onLineAfter: line) @@ -147,7 +147,7 @@ class PBXProjEncoderTests: XCTestCase { try loadFileSharedAcrossTargetsProject() let settings = PBXOutputSettings(projFileListOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) var line = lines.validate(line: "/* Begin PBXFileReference section */") line = lines.validate(lineContaining: "6C103BFA2A49CC5300D7EFE4 /* FileSharedAcrossTargets.framework */", onLineAfter: line) line = lines.validate(lineContaining: "6C103BFD2A49CC5300D7EFE4 /* FileSharedAcrossTargets.h */", onLineAfter: line) @@ -163,7 +163,7 @@ class PBXProjEncoderTests: XCTestCase { func test_navigator_groups_in_default_order_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) let beginGroup = lines.findLine("/* Begin PBXGroup section */") @@ -207,7 +207,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projNavigatorFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin PBXGroup section */") @@ -248,7 +248,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projNavigatorFileOrder: .byFilenameGroupsFirst) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin PBXGroup section */") @@ -290,7 +290,7 @@ class PBXProjEncoderTests: XCTestCase { func test_build_phase_sources_unsorted_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) let beginGroup = lines.findLine("/* Begin PBXSourcesBuildPhase section */") let files = lines.findLine("files = (", after: beginGroup) let endGroup = lines.findLine("/* End PBXSourcesBuildPhase section */") @@ -303,7 +303,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin PBXSourcesBuildPhase section */") var line = lines.findLine("files = (", after: beginGroup) line = lines.validate(line: "23766C161EAA3484007A9026 /* AppDelegate.swift in Sources */,", after: line) @@ -315,7 +315,7 @@ class PBXProjEncoderTests: XCTestCase { func test_build_phase_headers_unsorted_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) let beginGroup = lines.findLine("/* Begin PBXHeadersBuildPhase section */") let files = lines.findLine("files = (", after: beginGroup) let endGroup = lines.findLine("/* End PBXHeadersBuildPhase section */") @@ -328,7 +328,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin PBXHeadersBuildPhase section */") var line = lines.findLine("files = (", after: beginGroup) line = lines.validate(line: "04D5C0A51F153924008A2F98 /* Private.h in Headers */,", after: line) @@ -340,7 +340,7 @@ class PBXProjEncoderTests: XCTestCase { func test_build_phase_resources_unsorted_when_iOSProject() throws { try loadiOSProject() - let lines = self.lines(fromFile: encodeProject()) + let lines = lines(fromFile: encodeProject()) let beginGroup = lines.findLine("/* Begin PBXResourcesBuildPhase section */") let files = lines.findLine("files = (", after: beginGroup) let endGroup = lines.findLine("/* End PBXResourcesBuildPhase section */") @@ -353,7 +353,7 @@ class PBXProjEncoderTests: XCTestCase { try loadiOSProject() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin PBXResourcesBuildPhase section */") var line = lines.findLine("files = (", after: beginGroup) line = lines.validate(line: "23766C1D1EAA3484007A9026 /* Assets.xcassets in Resources */,", after: line) @@ -361,12 +361,12 @@ class PBXProjEncoderTests: XCTestCase { line = lines.validate(line: "23766C1B1EAA3484007A9026 /* Main.storyboard in Resources */,", after: line) line = lines.validate(line: "/* End PBXResourcesBuildPhase section */", after: line) } - + func test_build_rules_when_targetWithCustomBuildRulesProject() throws { try loadTargetWithCustomBuildRulesProject() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("6CAD68202A56E31400662D8A /* PBXBuildRule */ = {") var line = lines.validate(line: "isa = PBXBuildRule;", after: beginGroup) line = lines.validate(line: "compilerSpec = com.apple.compilers.proxy.script;", after: line) @@ -386,7 +386,7 @@ class PBXProjEncoderTests: XCTestCase { try loadProjectWithXCLocalSwiftPackageReference() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("/* Begin XCLocalSwiftPackageReference section */") var line = lines.validate(line: "C9FDF5C52AD604310096A37A /* XCLocalSwiftPackageReference \"MyLocalPackage\" */ = {", after: beginGroup) line = lines.validate(line: "isa = XCLocalSwiftPackageReference;", after: line) @@ -399,7 +399,7 @@ class PBXProjEncoderTests: XCTestCase { try loadProjectWithXCLocalSwiftPackageReference() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("packageReferences = (") var line = lines.validate(line: "42AA19FF22AAF0D600428760 /* XCRemoteSwiftPackageReference \"RxSwift\" */,", after: beginGroup) line = lines.validate(line: "C9FDF5C52AD604310096A37A /* XCLocalSwiftPackageReference \"MyLocalPackage\" */,", after: line) @@ -410,7 +410,7 @@ class PBXProjEncoderTests: XCTestCase { try loadProjectWithRelativeXCLocalSwiftPackageReference() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("packageReferences = (") var line = lines.validate(line: "C9FDF5C82AD8AE400096A37A /* XCLocalSwiftPackageReference \"../MyLocalPackage\" */,", after: beginGroup) line = lines.validate(line: ");", after: line) @@ -420,7 +420,7 @@ class PBXProjEncoderTests: XCTestCase { try loadProjectWithXCLocalSwiftPackageReferences() let settings = PBXOutputSettings(projBuildPhaseFileOrder: .byFilename) - let lines = self.lines(fromFile: encodeProject(settings: settings)) + let lines = lines(fromFile: encodeProject(settings: settings)) let beginGroup = lines.findLine("packageReferences = (") var line = lines.validate(line: "C9FDF5C52AD604310096A37A /* XCLocalSwiftPackageReference \"MyLocalPackage\" */,", after: beginGroup) line = lines.validate(line: "C9FDF5CB2AD8B3B50096A37A /* XCLocalSwiftPackageReference \"MyOtherLocalPackage/MyOtherLocalPackage\" */,", after: line) @@ -438,7 +438,7 @@ class PBXProjEncoderTests: XCTestCase { } } - private func encodeProjectThrows(error expectedError: E, line: UInt = #line) where E: Error { + private func encodeProjectThrows(error expectedError: some Error, line: UInt = #line) { do { _ = try PBXProjEncoder(outputSettings: PBXOutputSettings()).encode(proj: proj) XCTFail("Expected '\(expectedError)' to be thrown", line: line) @@ -460,7 +460,7 @@ class PBXProjEncoderTests: XCTestCase { private func loadFileSharedAcrossTargetsProject() throws { proj = try PBXProj(jsonDictionary: fileSharedAcrossTargetsDictionary().1) } - + private func loadTargetWithCustomBuildRulesProject() throws { proj = try PBXProj(jsonDictionary: targetWithCustomBuildRulesDictionary().1) } @@ -480,7 +480,7 @@ class PBXProjEncoderTests: XCTestCase { // MARK: - Line validations -private extension Array where Element == String { +private extension [String] { @discardableResult func validate(line string: String, betweenLine lineAbove: Int, andLine lineBelow: Int, line: UInt = #line) -> Int { validate(string, using: { $0 == $1 }, betweenLine: lineAbove, andLine: lineBelow, line: line) } diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProjIntegrationTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXProjIntegrationTests.swift index 93838e4d..fc442ca7 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProjIntegrationTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProjIntegrationTests.swift @@ -9,7 +9,7 @@ final class PBXProjIntegrationTests: XCTestCase { let decoder = XcodeprojPropertyListDecoder() let proj = try? decoder.decode(PBXProj.self, from: data) XCTAssertNotNil(proj) - if let proj = proj { + if let proj { assert(proj: proj) } } @@ -30,7 +30,7 @@ final class PBXProjIntegrationTests: XCTestCase { try? tmpDir.delete() } - let fixturePath = self.fixturePath().parent() + let fixturePath = fixturePath().parent() let xcodeprojPath = tmpDir + "Project.xcodeproj" try fixturePath.copy(xcodeprojPath) @@ -40,7 +40,7 @@ final class PBXProjIntegrationTests: XCTestCase { try checkedOutput("git", ["add", "."]) try checkedOutput("git", [ "-c", "user.email=test@example.com", "-c", "user.name=Test User", - "commit", "-m", "test" + "commit", "-m", "test", ]) // Read/write the project diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProject+Fixtures.swift b/Tests/XcodeProjTests/Objects/Project/PBXProject+Fixtures.swift index 66e8f916..69521592 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProject+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProject+Fixtures.swift @@ -5,7 +5,8 @@ extension PBXProject { static func fixture(name: String = "test", buildConfigurationList: XCConfigurationList = XCConfigurationList.fixture(), compatibilityVersion: String = Xcode.Default.compatibilityVersion, - mainGroup: PBXGroup = PBXGroup.fixture()) -> PBXProject { + mainGroup: PBXGroup = PBXGroup.fixture()) -> PBXProject + { PBXProject(name: name, buildConfigurationList: buildConfigurationList, compatibilityVersion: compatibilityVersion, diff --git a/Tests/XcodeProjTests/Objects/SwiftPackage/XCLocalSwiftPackageReferenceTests.swift b/Tests/XcodeProjTests/Objects/SwiftPackage/XCLocalSwiftPackageReferenceTests.swift index 9586ae35..119b96fc 100644 --- a/Tests/XcodeProjTests/Objects/SwiftPackage/XCLocalSwiftPackageReferenceTests.swift +++ b/Tests/XcodeProjTests/Objects/SwiftPackage/XCLocalSwiftPackageReferenceTests.swift @@ -30,7 +30,7 @@ final class XCLocalSwiftPackageReferenceTests: XCTestCase { // Then XCTAssertEqual(got.value, .dictionary([ "isa": "XCLocalSwiftPackageReference", - "relativePath": "repository" + "relativePath": "repository", ])) } diff --git a/Tests/XcodeProjTests/Objects/Targets/PBXTarget+Fixtures.swift b/Tests/XcodeProjTests/Objects/Targets/PBXTarget+Fixtures.swift index 84e882f5..07da826a 100644 --- a/Tests/XcodeProjTests/Objects/Targets/PBXTarget+Fixtures.swift +++ b/Tests/XcodeProjTests/Objects/Targets/PBXTarget+Fixtures.swift @@ -10,7 +10,8 @@ extension PBXTarget { dependencies: [PBXTargetDependency] = [], productName: String? = "Test", product: PBXFileReference = PBXFileReference.fixture(name: "Test.app"), - productType: PBXProductType = PBXProductType.application) -> PBXTarget { + productType: PBXProductType = PBXProductType.application) -> PBXTarget + { PBXTarget(name: name, buildConfigurationList: buildConfigurationList, buildPhases: buildPhases, diff --git a/Tests/XcodeProjTests/Project/XCBreakpointListTests.swift b/Tests/XcodeProjTests/Project/XCBreakpointListTests.swift index 44783730..1d1da4d8 100644 --- a/Tests/XcodeProjTests/Project/XCBreakpointListTests.swift +++ b/Tests/XcodeProjTests/Project/XCBreakpointListTests.swift @@ -12,7 +12,7 @@ final class XCBreakpointListIntegrationTests: XCTestCase { func test_init_initializesTheBreakpointListCorrectly() { XCTAssertNotNil(subject) - if let subject = subject { + if let subject { assert(breakpointList: subject) } } diff --git a/Tests/XcodeProjTests/Project/XCUserDataTests.swift b/Tests/XcodeProjTests/Project/XCUserDataTests.swift index 0f3b76d0..1918584f 100644 --- a/Tests/XcodeProjTests/Project/XCUserDataTests.swift +++ b/Tests/XcodeProjTests/Project/XCUserDataTests.swift @@ -14,11 +14,11 @@ final class XCUserDataTests: XCTestCase { initModel: { try? XCUserData(path: $0) }, modify: { userData in // XCScheme's that are already in place (the removed element) should not be removed by a write - userData.schemes = userData.schemes.filter { $0.name != "iOS-other"} + userData.schemes = userData.schemes.filter { $0.name != "iOS-other" } return userData }, assertion: { - assert(userData: $1, userName: "copy") + assert(userData: $1, userName: "copy") }) } diff --git a/Tests/XcodeProjTests/Project/XcodeProjTests.swift b/Tests/XcodeProjTests/Project/XcodeProjTests.swift index 3f4a8194..424767ed 100644 --- a/Tests/XcodeProjTests/Project/XcodeProjTests.swift +++ b/Tests/XcodeProjTests/Project/XcodeProjTests.swift @@ -24,7 +24,7 @@ final class XcodeProjIntegrationTests: XCTestCase { try testReadWriteProducesNoDiff(from: iosProjectPath, initModel: XcodeProj.init(path:)) } - + func test_initialize_PBXProj_with_data() throws { // Given let pbxprojPath = iosProjectPath + "project.pbxproj" @@ -38,7 +38,7 @@ final class XcodeProjIntegrationTests: XCTestCase { // Then XCTAssertEqual(pbxprojFromData, pbxprojFromDisk) } - + func test_write_includes_workspace_settings() throws { // Define workspace settings that should be written let workspaceSettings = WorkspaceSettings(buildSystem: .new, derivedDataLocationStyle: .default, autoCreateSchemes: false) diff --git a/Tests/XcodeProjTests/Scheme/XCScheme+BuildableReferenceTests.swift b/Tests/XcodeProjTests/Scheme/XCScheme+BuildableReferenceTests.swift index d1ee337d..776803ad 100644 --- a/Tests/XcodeProjTests/Scheme/XCScheme+BuildableReferenceTests.swift +++ b/Tests/XcodeProjTests/Scheme/XCScheme+BuildableReferenceTests.swift @@ -1,5 +1,5 @@ -@testable import XcodeProj import XCTest +@testable import XcodeProj final class XCSchemeBuildableReferenceTests: XCTestCase { func test_hash() throws { diff --git a/Tests/XcodeProjTests/Scheme/XCSchemeManagementTests.swift b/Tests/XcodeProjTests/Scheme/XCSchemeManagementTests.swift index f94252f4..ed33c974 100644 --- a/Tests/XcodeProjTests/Scheme/XCSchemeManagementTests.swift +++ b/Tests/XcodeProjTests/Scheme/XCSchemeManagementTests.swift @@ -1,17 +1,17 @@ -import Foundation -import XCTest import AEXML +import Foundation import PathKit +import XCTest @testable import XcodeProj final class XCSchemeManagementTests: XCTestCase { func test_init_from_path() throws { // Given let path = xcschememanagementPath - + // When - let got = try XCSchemeManagement.init(path: path) - + let got = try XCSchemeManagement(path: path) + // Then XCTAssertEqual(got.suppressBuildableAutocreation, [ "E525238B16245A900012E2BA": .init(primary: true), @@ -35,7 +35,7 @@ final class XCSchemeManagementTests: XCTestCase { let path = xcschememanagementPath // When - let reads = try (0..<10).map { _ in + let reads = try (0 ..< 10).map { _ in try XCSchemeManagement(path: path) } @@ -65,12 +65,12 @@ final class XCSchemeManagementTests: XCTestCase { ] ) try subject.write(path: plistPath, override: true) - + // Create a commit try checkedOutput("git", ["init"]) try checkedOutput("git", ["add", "."]) try checkedOutput("git", ["commit", "-m", "test"]) - + // Write again try subject.write(path: plistPath, override: true) diff --git a/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift b/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift index 1c79171d..d4ed343c 100644 --- a/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift +++ b/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift @@ -25,7 +25,7 @@ final class XCSchemeIntegrationTests: XCTestCase { let subject = try? XCScheme(path: runnableWithoutBuildableReferenceSchemePath) XCTAssertNotNil(subject) - if let subject = subject { + if let subject { assert(runnableWithoutBuildableReferenceScheme: subject) } } @@ -53,7 +53,7 @@ final class XCSchemeIntegrationTests: XCTestCase { let subject = try? XCScheme(path: minimalSchemePath) XCTAssertNotNil(subject) - if let subject = subject { + if let subject { assert(minimalScheme: subject) } } @@ -331,7 +331,7 @@ final class XCSchemeIntegrationTests: XCTestCase { // Then XCTAssertEqual(reconstructedSubject, subject) } - + func test_buildAction_buildArchitectures() throws { // Given / When let subject = try XCScheme(path: buildArchitecturesSchemePath) @@ -340,7 +340,7 @@ final class XCSchemeIntegrationTests: XCTestCase { let buildAction = try XCTUnwrap(subject.buildAction) XCTAssertTrue(buildAction.buildArchitectures == .matchRunDestination) } - + func test_buildAction_buildArchitectures_whenXMLElementDoesNotExist() throws { // Given / When let subject = try XCScheme(path: minimalSchemePath) @@ -349,7 +349,7 @@ final class XCSchemeIntegrationTests: XCTestCase { let buildAction = try XCTUnwrap(subject.buildAction) XCTAssertTrue(buildAction.buildArchitectures == .useTargetSettings) } - + func test_buildAction_buildArchitectures_serializingAndDeserializing() throws { // Given let scheme = try XCScheme(path: buildArchitecturesSchemePath) @@ -774,7 +774,7 @@ final class XCSchemeIntegrationTests: XCTestCase { // A scheme with the `runPostActionsOnFailure` enabled fixturesPath() + "Schemes/RunPostActionsOnFailure.xcscheme" } - + /// A scheme that `buildArchitectures` is specified "Automatic". private var buildArchitecturesSchemePath: Path { fixturesPath() + "Schemes/BuildArchitectures.xcscheme" diff --git a/Tests/XcodeProjTests/Tests/Fixtures.swift b/Tests/XcodeProjTests/Tests/Fixtures.swift index b90f5d14..40cc343f 100644 --- a/Tests/XcodeProjTests/Tests/Fixtures.swift +++ b/Tests/XcodeProjTests/Tests/Fixtures.swift @@ -16,7 +16,6 @@ func fileSharedAcrossTargetsDictionary() -> (Path, [String: Any]) { return (fileSharedAcrossTargetsProject, loadPlist(path: fileSharedAcrossTargetsProject.string)!) } - func targetWithCustomBuildRulesDictionary() -> (Path, [String: Any]) { let targetWithCustomBuildRulesProject = fixturesPath() + "TargetWithCustomBuildRules/TargetWithCustomBuildRules.xcodeproj/project.pbxproj" return (targetWithCustomBuildRulesProject, loadPlist(path: targetWithCustomBuildRulesProject.string)!) diff --git a/Tests/XcodeProjTests/Tests/testWrite.swift b/Tests/XcodeProjTests/Tests/testWrite.swift index 01e8ebfc..44d719d5 100644 --- a/Tests/XcodeProjTests/Tests/testWrite.swift +++ b/Tests/XcodeProjTests/Tests/testWrite.swift @@ -7,7 +7,8 @@ func testWrite(file _: StaticString = #file, line _: UInt = #line, from path: Path, initModel: (Path) -> T?, - modify: (T) -> T) { + modify: (T) -> T) +{ testWrite(from: path, initModel: initModel, modify: modify, assertion: { XCTAssertEqual($0, $1) }) } @@ -16,19 +17,20 @@ func testWrite(file: StaticString = #file, from path: Path, initModel: (Path) -> T?, modify: (T) -> T, - assertion: (_ before: T, _ after: T) -> Void) { + assertion: (_ before: T, _ after: T) -> Void) +{ let copyPath = path.parent() + "copy.\(path.extension!)" try? copyPath.delete() try? path.copy(copyPath) let got = initModel(copyPath) XCTAssertNotNil(got, file: file, line: line) - if let got = got { + if let got { let modified = modify(got) do { try modified.write(path: copyPath, override: true) let gotAfterWriting = initModel(copyPath) XCTAssertNotNil(gotAfterWriting, file: file, line: line) - if let gotAfterWriting = gotAfterWriting { + if let gotAfterWriting { assertion(got, gotAfterWriting) } } catch { @@ -38,10 +40,11 @@ func testWrite(file: StaticString = #file, try? copyPath.delete() } -func testReadWriteProducesNoDiff(file: StaticString = #file, - line: UInt = #line, - from path: Path, - initModel: (Path) throws -> T) throws { +func testReadWriteProducesNoDiff(file _: StaticString = #file, + line _: UInt = #line, + from path: Path, + initModel: (Path) throws -> some Writable) throws +{ let tmpDir = try Path.uniqueTemporary() defer { try? tmpDir.delete() @@ -57,13 +60,13 @@ func testReadWriteProducesNoDiff(file: StaticString = #file, try checkedOutput("git", ["add", "."]) try checkedOutput("git", [ "-c", "user.email=test@example.com", "-c", "user.name=Test User", - "commit", "-m", "test" + "commit", "-m", "test", ]) let object = try initModel(tmpPath) try object.write(path: tmpPath, override: true) - let diff = try XCTUnwrap(try checkedOutput("git", ["diff"])) + let diff = try XCTUnwrap(checkedOutput("git", ["diff"])) XCTAssertEqual(diff, "") } } diff --git a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift index 08a3f976..e16035d8 100644 --- a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift +++ b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift @@ -49,7 +49,7 @@ class ReferenceGeneratorTests: XCTestCase { try referenceGenerator.generateReferences(proj: project) return [remoteProjectFileReference, containerItemProxy, productReferenceProxy, productsGroup, buildFile, pluginDependency.productReference!.getObject()!] - .map { $0.reference.value } + .map(\.reference.value) } let firstUUIDs = try generateProject() diff --git a/Tests/XcodeProjTests/Utils/XCConfigTests.swift b/Tests/XcodeProjTests/Utils/XCConfigTests.swift index ade947b4..afb249cd 100644 --- a/Tests/XcodeProjTests/Utils/XCConfigTests.swift +++ b/Tests/XcodeProjTests/Utils/XCConfigTests.swift @@ -13,7 +13,7 @@ final class XCConfigTests: XCTestCase { (Path("testA"), configA), (Path("testB"), configB), ], - buildSettings: ["a": "b"]) + buildSettings: ["a": "b"]) XCTAssertEqual(config.buildSettings as! [String: String], ["a": "b"]) XCTAssertEqual(config.includes[0].config, configA) XCTAssertEqual(config.includes[1].config, configB) @@ -26,7 +26,7 @@ final class XCConfigTests: XCTestCase { (Path("testA"), configA), (Path("testB"), configB), ], - buildSettings: ["b": "3"]) + buildSettings: ["b": "3"]) let buildSettings = config.flattenedBuildSettings() XCTAssertEqual(buildSettings["a"] as? String, "2") XCTAssertEqual(buildSettings["b"] as? String, "3") @@ -81,7 +81,7 @@ final class XCConfigIntegrationTests: XCTestCase { func test_init_initializesXCConfigWithTheRightProperties() { let subject = try? XCConfig(path: childrenPath()) XCTAssertNotNil(subject) - if let subject = subject { + if let subject { assert(config: subject) } } From b32ae6214d8f5ea1e7f39504df840321b97878f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era=20Buend=C3=ADa?= <663605+pepicrft@users.noreply.github.com> Date: Sat, 10 Aug 2024 18:23:43 +0200 Subject: [PATCH 07/13] feat: Introduce the new Xcode 16 models `PBXFileSystemSynchronizedRootGroup` and `PBXFileSystemSynchronizedBuildFileExceptionSet` (#827) * Add PBXFileSystemSynchronizedRootGroup and property to PBXTarget * Implement the new models * Add publicHeaders and privateHeaders * Fix some bugs and add some tests * Fix some linting issues * Fix the pipeline to not run twice on PRs * Add tests * feat: Add optional exceptions to PBXFileSystemSynchronizedRootGroup * fix!: Fix non-determinism reading and writing the packageProductDependencies attribute of PBXTarget * Fix issues after rebasing * Update Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedRootGroup.swift Co-authored-by: Kas * Add missing attributes --------- Co-authored-by: Kas --- .github/workflows/xcodeproj.yml | 7 +- .gitignore | 3 + .mise.toml | 3 +- .../project.pbxproj | 359 ++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 14 + .../Exception/Exception.swift | 6 + .../SynchronizedRootGroups.swift | 6 + ...temSynchronizedBuildFileExceptionSet.swift | 110 ++++++ .../PBXFileSystemSynchronizedRootGroup.swift | 109 ++++++ .../XcodeProj/Objects/Files/PBXGroup.swift | 10 + .../Objects/Project/PBXObjectParser.swift | 4 + .../Objects/Project/PBXObjects.swift | 27 +- .../Objects/Project/PBXProjEncoder.swift | 12 + .../Objects/Project/PBXProject.swift | 4 +- .../Objects/Sourcery/Equality.generated.swift | 21 + .../XcodeProj/Objects/Targets/PBXTarget.swift | 53 ++- .../XcodeProj/Utils/ReferenceGenerator.swift | 2 +- ...onizedBuildFileExceptionSet+Fixtures.swift | 17 + ...nchronizedBuildFileExceptionSetTests.swift | 29 ++ ...SystemSynchronizedRootGroup+Fixtures.swift | 27 ++ ...FileSystemSynchronizedRootGroupTests.swift | 51 +++ .../Objects/Project/PBXProjEncoderTests.swift | 36 ++ .../Objects/Project/PBXProjectTests.swift | 6 +- ....swift => XcodeProjIntegrationTests.swift} | 9 + Tests/XcodeProjTests/Tests/Fixtures.swift | 5 + 25 files changed, 911 insertions(+), 19 deletions(-) create mode 100644 Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/project.pbxproj create mode 100644 Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/xcuserdata/pepicrft.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/Exception/Exception.swift create mode 100644 Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/SynchronizedRootGroups.swift create mode 100644 Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift create mode 100644 Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedRootGroup.swift create mode 100644 Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet+Fixtures.swift create mode 100644 Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSetTests.swift create mode 100644 Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroup+Fixtures.swift create mode 100644 Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroupTests.swift rename Tests/XcodeProjTests/Project/{XcodeProjTests.swift => XcodeProjIntegrationTests.swift} (89%) diff --git a/.github/workflows/xcodeproj.yml b/.github/workflows/xcodeproj.yml index 7d921922..5d1e3b5f 100644 --- a/.github/workflows/xcodeproj.yml +++ b/.github/workflows/xcodeproj.yml @@ -1,7 +1,11 @@ # https://help.github.com/en/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idname name: XcodeProj -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: {} concurrency: group: xcodeproj-${{ github.head_ref }} @@ -52,6 +56,7 @@ jobs: git config --global init.defaultBranch main - name: Build and run tests run: swift test --enable-test-discovery + lint: name: Lint runs-on: macos-latest diff --git a/.gitignore b/.gitignore index 97f05bc9..a53f04dd 100644 --- a/.gitignore +++ b/.gitignore @@ -190,3 +190,6 @@ XcodeProj.framework.zip Derived/ *.xcworkspace/ *.xcodeproj/ + +!Fixtures/**/*.xcodeproj/ + diff --git a/.mise.toml b/.mise.toml index 317af7dd..ec954e15 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,3 +1,4 @@ [tools] -swiftlint = "0.54.0" swiftformat = "0.54.3" +tuist = "4.21.2" +swiftlint = "0.55.1" diff --git a/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/project.pbxproj b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/project.pbxproj new file mode 100644 index 00000000..5db92414 --- /dev/null +++ b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/project.pbxproj @@ -0,0 +1,359 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 70; + objects = { + +/* Begin PBXFileReference section */ + 6CF05B8C2C53F5F200EF267F /* SynchronizedRootGroups.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SynchronizedRootGroups.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 6CF05BA32C53F97F00EF267F /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Exception/Exception.swift, + ); + target = 6CF05B8B2C53F5F200EF267F /* SynchronizedRootGroups */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 6CF05B9D2C53F64800EF267F /* SynchronizedRootGroups */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (6CF05BA32C53F97F00EF267F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SynchronizedRootGroups; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6CF05B892C53F5F200EF267F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6CF05B822C53F5F200EF267F = { + isa = PBXGroup; + children = ( + 6CF05B9D2C53F64800EF267F /* SynchronizedRootGroups */, + 6CF05B8D2C53F5F200EF267F /* Products */, + ); + sourceTree = ""; + }; + 6CF05B8D2C53F5F200EF267F /* Products */ = { + isa = PBXGroup; + children = ( + 6CF05B8C2C53F5F200EF267F /* SynchronizedRootGroups.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 6CF05B872C53F5F200EF267F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 6CF05B8B2C53F5F200EF267F /* SynchronizedRootGroups */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6CF05B922C53F5F200EF267F /* Build configuration list for PBXNativeTarget "SynchronizedRootGroups" */; + buildPhases = ( + 6CF05B872C53F5F200EF267F /* Headers */, + 6CF05B882C53F5F200EF267F /* Sources */, + 6CF05B892C53F5F200EF267F /* Frameworks */, + 6CF05B8A2C53F5F200EF267F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 6CF05B9D2C53F64800EF267F /* SynchronizedRootGroups */, + ); + name = SynchronizedRootGroups; + packageProductDependencies = ( + ); + productName = SynchronizedRootGroups; + productReference = 6CF05B8C2C53F5F200EF267F /* SynchronizedRootGroups.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6CF05B832C53F5F200EF267F /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1600; + TargetAttributes = { + 6CF05B8B2C53F5F200EF267F = { + CreatedOnToolsVersion = 16.0; + LastSwiftMigration = 1600; + }; + }; + }; + buildConfigurationList = 6CF05B862C53F5F200EF267F /* Build configuration list for PBXProject "SynchronizedRootGroups" */; + compatibilityVersion = "Xcode 15.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6CF05B822C53F5F200EF267F; + productRefGroup = 6CF05B8D2C53F5F200EF267F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6CF05B8B2C53F5F200EF267F /* SynchronizedRootGroups */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6CF05B8A2C53F5F200EF267F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6CF05B882C53F5F200EF267F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 6CF05B932C53F5F200EF267F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = io.tuist.SynchronizedRootGroups; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 6CF05B942C53F5F200EF267F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = io.tuist.SynchronizedRootGroups; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 6CF05B952C53F5F200EF267F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 6CF05B962C53F5F200EF267F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6CF05B862C53F5F200EF267F /* Build configuration list for PBXProject "SynchronizedRootGroups" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6CF05B952C53F5F200EF267F /* Debug */, + 6CF05B962C53F5F200EF267F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6CF05B922C53F5F200EF267F /* Build configuration list for PBXNativeTarget "SynchronizedRootGroups" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6CF05B932C53F5F200EF267F /* Debug */, + 6CF05B942C53F5F200EF267F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6CF05B832C53F5F200EF267F /* Project object */; +} diff --git a/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/xcuserdata/pepicrft.xcuserdatad/xcschemes/xcschememanagement.plist b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/xcuserdata/pepicrft.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..e04d3354 --- /dev/null +++ b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/xcuserdata/pepicrft.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + SynchronizedRootGroups.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/Exception/Exception.swift b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/Exception/Exception.swift new file mode 100644 index 00000000..190cf0a7 --- /dev/null +++ b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/Exception/Exception.swift @@ -0,0 +1,6 @@ +// +// Exception.swift +// SynchronizedRootGroups +// +// Created by Pedro Piñera Buendía on 26.07.24. +// diff --git a/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/SynchronizedRootGroups.swift b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/SynchronizedRootGroups.swift new file mode 100644 index 00000000..9286b780 --- /dev/null +++ b/Fixtures/SynchronizedRootGroups/SynchronizedRootGroups/SynchronizedRootGroups.swift @@ -0,0 +1,6 @@ +// +// SynchronizedRootGroups.swift +// SynchronizedRootGroups +// +// Created by Pedro Piñera Buendía on 26.07.24. +// diff --git a/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift new file mode 100644 index 00000000..572380cf --- /dev/null +++ b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift @@ -0,0 +1,110 @@ +import Foundation + +/// Class representing an element that may contain other elements. +public class PBXFileSystemSynchronizedBuildFileExceptionSet: PBXObject, PlistSerializable { + // MARK: - Attributes + + /// A list of relative paths to children subfolders for which exceptions are applied. + public var membershipExceptions: [String]? + + /// Changes the default header visibility (project) to public for the following headers. + /// Every item in the list is the relative path inside the root synchronized group. + public var publicHeaders: [String]? + + /// Changes the default header visibility (project) to private for the following headers. + /// Every item in the list is the relative path inside the root synchronized group. + public var privateHeaders: [String]? + + /// Additional compiler flags by relative path. + /// Every item in the list is the relative path inside the root synchronized group. + /// The value is the additional compiler flags. + public var additionalCompilerFlagsByRelativePath: [String: String]? + + /// Attributes by relative path. + /// Every item in the list is the relative path inside the root synchronized group. + /// This is used for example when linking frameworks to specify that they are optional with the attribute "Weak" + public var attributesByRelativePath: [String: [String]]? + + var targetReference: PBXObjectReference + + public var target: PBXTarget! { + get { + targetReference.getObject() as? PBXTarget + } + set { + targetReference = newValue.reference + } + } + + // MARK: - Init + + public init(target: PBXTarget, membershipExceptions: [String]?, publicHeaders: [String]?, privateHeaders: [String]?, additionalCompilerFlagsByRelativePath: [String: String]?, attributesByRelativePath: [String: [String]]?) { + targetReference = target.reference + self.membershipExceptions = membershipExceptions + self.publicHeaders = publicHeaders + self.privateHeaders = privateHeaders + self.additionalCompilerFlagsByRelativePath = additionalCompilerFlagsByRelativePath + self.attributesByRelativePath = attributesByRelativePath + super.init() + } + + // MARK: - Decodable + + fileprivate enum CodingKeys: String, CodingKey { + case target + case membershipExceptions + case publicHeaders + case privateHeaders + case additionalCompilerFlagsByRelativePath + case attributesByRelativePath + } + + public required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let referenceRepository = decoder.context.objectReferenceRepository + let objects = decoder.context.objects + let targetReference: String = try container.decode(.target) + self.targetReference = referenceRepository.getOrCreate(reference: targetReference, objects: objects) + membershipExceptions = try container.decodeIfPresent(.membershipExceptions) + publicHeaders = try container.decodeIfPresent(.publicHeaders) + privateHeaders = try container.decodeIfPresent(.privateHeaders) + additionalCompilerFlagsByRelativePath = try container.decodeIfPresent(.additionalCompilerFlagsByRelativePath) + attributesByRelativePath = try container.decodeIfPresent(.attributesByRelativePath) + try super.init(from: decoder) + } + + // MARK: - Equatable + + override func isEqual(to object: Any?) -> Bool { + guard let rhs = object as? PBXFileSystemSynchronizedBuildFileExceptionSet else { return false } + return isEqual(to: rhs) + } + + // MARK: - PlistSerializable + + func plistKeyAndValue(proj _: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { + var dictionary: [CommentedString: PlistValue] = [:] + dictionary["isa"] = .string(CommentedString(PBXFileSystemSynchronizedBuildFileExceptionSet.isa)) + if let membershipExceptions { + dictionary["membershipExceptions"] = .array(membershipExceptions.map { .string(CommentedString($0)) }) + } + if let publicHeaders { + dictionary["publicHeaders"] = .array(publicHeaders.map { .string(CommentedString($0)) }) + } + if let privateHeaders { + dictionary["privateHeaders"] = .array(privateHeaders.map { .string(CommentedString($0)) }) + } + if let additionalCompilerFlagsByRelativePath { + dictionary["additionalCompilerFlagsByRelativePath"] = .dictionary(Dictionary(uniqueKeysWithValues: additionalCompilerFlagsByRelativePath.map { key, value in + (CommentedString(key), PlistValue.string(CommentedString(value))) + })) + } + if let attributesByRelativePath { + dictionary["attributesByRelativePath"] = .dictionary(Dictionary(uniqueKeysWithValues: attributesByRelativePath.map { key, value in + (CommentedString(key), .array(value.map { .string(CommentedString($0)) })) + })) + } + dictionary["target"] = .string(CommentedString(target.reference.value, comment: target.name)) + return (key: CommentedString(reference, comment: "PBXFileSystemSynchronizedBuildFileExceptionSet"), value: .dictionary(dictionary)) + } +} diff --git a/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedRootGroup.swift b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedRootGroup.swift new file mode 100644 index 00000000..5df7fe34 --- /dev/null +++ b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedRootGroup.swift @@ -0,0 +1,109 @@ +import Foundation +import PathKit + +public class PBXFileSystemSynchronizedRootGroup: PBXFileElement { + /// It maps relative paths inside the synchronized root group to a particular file type. + /// If a path doesn't have a particular file type specified, Xcode defaults to the default file type + /// based on the extension of the file. + public var explicitFileTypes: [String: String] + + /// Returns the references of the exceptions. + var exceptionsReferences: [PBXObjectReference]? + + /// It returns a list of exception objects that override the configuration for some children + /// in the synchronized root group. + public var exceptions: [PBXFileSystemSynchronizedBuildFileExceptionSet]? { + set { + exceptionsReferences = newValue?.references() + } + get { + exceptionsReferences?.objects() + } + } + + /// A list of relative paths to children folder whose configuration is overriden. + public var explicitFolders: [String] + + /// Initializes the file element with its properties. + /// + /// - Parameters: + /// - sourceTree: file source tree. + /// - path: object relative path from `sourceTree`, if different than `name`. + /// - name: object name. + /// - includeInIndex: should the IDE index the object? + /// - usesTabs: object uses tabs. + /// - indentWidth: the number of positions to indent blocks of code + /// - tabWidth: the visual width of tab characters + /// - wrapsLines: should the IDE wrap lines when editing the object? + /// - explicitFileTypes: It maps relative paths inside the synchronized root group to a particular file type. + /// - exceptions: It returns a list of exception objects that override the configuration for some children in the synchronized root group. + /// - explicitFolders: A list of relative paths to children folder whose configuration is overriden. + public init(sourceTree: PBXSourceTree? = nil, + path: String? = nil, + name: String? = nil, + includeInIndex: Bool? = nil, + usesTabs: Bool? = nil, + indentWidth: UInt? = nil, + tabWidth: UInt? = nil, + wrapsLines: Bool? = nil, + explicitFileTypes: [String: String] = [:], + exceptions: [PBXFileSystemSynchronizedBuildFileExceptionSet] = [], + explicitFolders: [String] = []) { + self.explicitFileTypes = explicitFileTypes + exceptionsReferences = exceptions.references() + self.explicitFolders = explicitFolders + super.init(sourceTree: sourceTree, + path: path, + name: name, + includeInIndex: includeInIndex, + usesTabs: usesTabs, + indentWidth: indentWidth, + tabWidth: tabWidth, + wrapsLines: wrapsLines) + } + + // MARK: - Decodable + + fileprivate enum CodingKeys: String, CodingKey { + case explicitFileTypes + case exceptions + case explicitFolders + } + + public required init(from decoder: Decoder) throws { + let objects = decoder.context.objects + let objectReferenceRepository = decoder.context.objectReferenceRepository + let container = try decoder.container(keyedBy: CodingKeys.self) + explicitFileTypes = try (container.decodeIfPresent(.explicitFileTypes)) ?? [:] + let exceptionsReferences: [String] = try (container.decodeIfPresent(.exceptions)) ?? [] + self.exceptionsReferences = exceptionsReferences.map { objectReferenceRepository.getOrCreate(reference: $0, objects: objects) } + explicitFolders = try (container.decodeIfPresent(.explicitFolders)) ?? [] + try super.init(from: decoder) + } + + // MARK: - PlistSerializable + + override var multiline: Bool { false } + + override func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) { + var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:] + dictionary["isa"] = .string(CommentedString(type(of: self).isa)) + if let exceptionsReferences, !exceptionsReferences.isEmpty { + dictionary["exceptions"] = .array(exceptionsReferences.map { exceptionReference in + .string(CommentedString(exceptionReference.value, comment: "PBXFileSystemSynchronizedBuildFileExceptionSet")) + }) + } + dictionary["explicitFileTypes"] = .dictionary(Dictionary(uniqueKeysWithValues: explicitFileTypes.map { relativePath, fileType in + (CommentedString(relativePath), .string(CommentedString(fileType))) + })) + dictionary["explicitFolders"] = .array(explicitFolders.map { .string(CommentedString($0)) }) + return (key: CommentedString(reference, + comment: name ?? path), + value: .dictionary(dictionary)) + } + + override func isEqual(to object: Any?) -> Bool { + guard let rhs = object as? PBXFileSystemSynchronizedRootGroup else { return false } + return isEqual(to: rhs) + } +} diff --git a/Sources/XcodeProj/Objects/Files/PBXGroup.swift b/Sources/XcodeProj/Objects/Files/PBXGroup.swift index 05cece65..8b8d2814 100644 --- a/Sources/XcodeProj/Objects/Files/PBXGroup.swift +++ b/Sources/XcodeProj/Objects/Files/PBXGroup.swift @@ -116,6 +116,16 @@ public extension PBXGroup { .first(where: { $0.name == name }) } + /// Returns the synchronized root group with the given name contained in the given parent group. + /// + /// - Parameter groupName: group name. + /// - Returns: the synchronized root group with the given name contained in the given parent group. + func synchronizedRootGroup(named name: String) -> PBXFileSystemSynchronizedRootGroup? { + childrenReferences + .objects() + .first(where: { $0.name == name }) + } + /// Returns the file in the group with the given name. /// /// - Parameter name: file name. diff --git a/Sources/XcodeProj/Objects/Project/PBXObjectParser.swift b/Sources/XcodeProj/Objects/Project/PBXObjectParser.swift index ef80d046..3c0ad004 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjectParser.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjectParser.swift @@ -68,6 +68,10 @@ final class PBXObjectParser { return try decoder.decode(XCLocalSwiftPackageReference.self, from: data) case XCSwiftPackageProductDependency.isa: return try decoder.decode(XCSwiftPackageProductDependency.self, from: data) + case PBXFileSystemSynchronizedRootGroup.isa: + return try decoder.decode(PBXFileSystemSynchronizedRootGroup.self, from: data) + case PBXFileSystemSynchronizedBuildFileExceptionSet.isa: + return try decoder.decode(PBXFileSystemSynchronizedBuildFileExceptionSet.self, from: data) default: throw PBXObjectError.unknownElement(isa) } diff --git a/Sources/XcodeProj/Objects/Project/PBXObjects.swift b/Sources/XcodeProj/Objects/Project/PBXObjects.swift index 5fbf74e1..22cfe75c 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjects.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjects.swift @@ -135,6 +135,16 @@ class PBXObjects: Equatable { lock.whileLocked { _swiftPackageProductDependencies } } + private var _fileSystemSynchronizedRootGroups: [PBXObjectReference: PBXFileSystemSynchronizedRootGroup] = [:] + var fileSystemSynchronizedRootGroups: [PBXObjectReference: PBXFileSystemSynchronizedRootGroup] { + lock.whileLocked { _fileSystemSynchronizedRootGroups } + } + + private var _fileSystemSynchronizedBuildFileExceptionSets: [PBXObjectReference: PBXFileSystemSynchronizedBuildFileExceptionSet] = [:] + var fileSystemSynchronizedBuildFileExceptionSets: [PBXObjectReference: PBXFileSystemSynchronizedBuildFileExceptionSet] { + lock.whileLocked { _fileSystemSynchronizedBuildFileExceptionSets } + } + // XCSwiftPackageProductDependency /// Initializes the project objects container @@ -173,7 +183,9 @@ class PBXObjects: Equatable { lhs.carbonResourcesBuildPhases == rhs.carbonResourcesBuildPhases && lhs.buildRules == rhs.buildRules && lhs.swiftPackageProductDependencies == rhs._swiftPackageProductDependencies && - lhs.remoteSwiftPackageReferences == rhs.remoteSwiftPackageReferences + lhs.remoteSwiftPackageReferences == rhs.remoteSwiftPackageReferences && + lhs.fileSystemSynchronizedRootGroups == rhs.fileSystemSynchronizedRootGroups && + lhs.fileSystemSynchronizedBuildFileExceptionSets == rhs.fileSystemSynchronizedBuildFileExceptionSets } // MARK: - Helpers @@ -218,6 +230,8 @@ class PBXObjects: Equatable { case let object as XCRemoteSwiftPackageReference: _remoteSwiftPackageReferences[objectReference] = object case let object as XCLocalSwiftPackageReference: _localSwiftPackageReferences[objectReference] = object case let object as XCSwiftPackageProductDependency: _swiftPackageProductDependencies[objectReference] = object + case let object as PBXFileSystemSynchronizedRootGroup: _fileSystemSynchronizedRootGroups[objectReference] = object + case let object as PBXFileSystemSynchronizedBuildFileExceptionSet: _fileSystemSynchronizedBuildFileExceptionSets[objectReference] = object default: fatalError("Unhandled PBXObject type for \(object), this is likely a bug / todo") } } @@ -278,7 +292,12 @@ class PBXObjects: Equatable { return _remoteSwiftPackageReferences.remove(at: index).value } else if let index = swiftPackageProductDependencies.index(forKey: reference) { return _swiftPackageProductDependencies.remove(at: index).value + } else if let index = fileSystemSynchronizedRootGroups.index(forKey: reference) { + return _fileSystemSynchronizedRootGroups.remove(at: index).value + } else if let index = fileSystemSynchronizedBuildFileExceptionSets.index(forKey: reference) { + return _fileSystemSynchronizedBuildFileExceptionSets.remove(at: index).value } + return nil } @@ -340,6 +359,10 @@ class PBXObjects: Equatable { return object } else if let object = swiftPackageProductDependencies[reference] { return object + } else if let object = fileSystemSynchronizedRootGroups[reference] { + return object + } else if let object = fileSystemSynchronizedBuildFileExceptionSets[reference] { + return object } else { return nil } @@ -431,5 +454,7 @@ extension PBXObjects { carbonResourcesBuildPhases.values.forEach(closure) remoteSwiftPackageReferences.values.forEach(closure) swiftPackageProductDependencies.values.forEach(closure) + fileSystemSynchronizedRootGroups.values.forEach(closure) + fileSystemSynchronizedBuildFileExceptionSets.values.forEach(closure) } } diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index 9b0dd2f2..9ee78300 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -113,6 +113,18 @@ final class PBXProjEncoder { outputSettings: outputSettings, stateHolder: &stateHolder, to: &output) + try write(section: "PBXFileSystemSynchronizedBuildFileExceptionSet", + proj: proj, + objects: proj.objects.fileSystemSynchronizedBuildFileExceptionSets, + outputSettings: outputSettings, + stateHolder: &stateHolder, + to: &output) + try write(section: "PBXFileSystemSynchronizedRootGroup", + proj: proj, + objects: proj.objects.fileSystemSynchronizedRootGroups, + outputSettings: outputSettings, + stateHolder: &stateHolder, + to: &output) try write(section: "PBXFrameworksBuildPhase", proj: proj, objects: proj.objects.frameworksBuildPhases, diff --git a/Sources/XcodeProj/Objects/Project/PBXProject.swift b/Sources/XcodeProj/Objects/Project/PBXProject.swift index 79a3e148..378309da 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProject.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProject.swift @@ -443,7 +443,7 @@ extension PBXProject { productDependency = XCSwiftPackageProductDependency(productName: productName, package: reference) objects.add(object: productDependency) } - target.packageProductDependencies.append(productDependency) + target.packageProductDependencies?.append(productDependency) return productDependency } @@ -465,7 +465,7 @@ extension PBXProject { productDependency = XCSwiftPackageProductDependency(productName: productName) objects.add(object: productDependency) } - target.packageProductDependencies.append(productDependency) + target.packageProductDependencies?.append(productDependency) return productDependency } diff --git a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift index c20d93c2..4c9a1d98 100644 --- a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift +++ b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift @@ -301,3 +301,24 @@ extension XCVersionGroup { return super.isEqual(to: rhs) } } + +extension PBXFileSystemSynchronizedRootGroup { + /// :nodoc: + func isEqual(to rhs: PBXFileSystemSynchronizedRootGroup) -> Bool { + if explicitFileTypes != rhs.explicitFileTypes { return false } + if exceptionsReferences != rhs.exceptionsReferences { return false } + if explicitFolders != rhs.explicitFolders { return false } + return super.isEqual(to: rhs) + } +} + +extension PBXFileSystemSynchronizedBuildFileExceptionSet { + /// :nodoc: + func isEqual(to rhs: PBXFileSystemSynchronizedBuildFileExceptionSet) -> Bool { + if membershipExceptions != rhs.membershipExceptions { return false } + if targetReference != rhs.targetReference { return false } + if publicHeaders != rhs.publicHeaders { return false } + if privateHeaders != rhs.privateHeaders { return false } + return super.isEqual(to: rhs) + } +} diff --git a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift index 86646cfd..b23e0b47 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift @@ -76,15 +76,28 @@ public class PBXTarget: PBXContainerItem { } /// Swift package product references. - var packageProductDependencyReferences: [PBXObjectReference] + var packageProductDependencyReferences: [PBXObjectReference]? /// Swift packages products. - public var packageProductDependencies: [XCSwiftPackageProductDependency] { + public var packageProductDependencies: [XCSwiftPackageProductDependency]? { set { - packageProductDependencyReferences = newValue.references() + packageProductDependencyReferences = newValue?.references() } get { - packageProductDependencyReferences.objects() + packageProductDependencyReferences?.objects() + } + } + + // File system synchronized groups references. + var fileSystemSynchronizedGroupsReferences: [PBXObjectReference]? + + // File system synchronized groups. + public var fileSystemSynchronizedGroups: [PBXFileSystemSynchronizedRootGroup]? { + set { + fileSystemSynchronizedGroupsReferences = newValue?.references() + } + get { + fileSystemSynchronizedGroupsReferences?.objects() } } @@ -110,12 +123,14 @@ public class PBXTarget: PBXContainerItem { packageProductDependencies: [XCSwiftPackageProductDependency] = [], productName: String? = nil, product: PBXFileReference? = nil, - productType: PBXProductType? = nil) { + productType: PBXProductType? = nil, + fileSystemSynchronizedGroups: [PBXFileSystemSynchronizedRootGroup]? = nil) { buildConfigurationListReference = buildConfigurationList?.reference buildPhaseReferences = buildPhases.references() buildRuleReferences = buildRules.references() dependencyReferences = dependencies.references() packageProductDependencyReferences = packageProductDependencies.references() + fileSystemSynchronizedGroupsReferences = fileSystemSynchronizedGroups?.references() self.name = name self.productName = productName productReference = product?.reference @@ -135,6 +150,7 @@ public class PBXTarget: PBXContainerItem { case productReference case productType case packageProductDependencies + case fileSystemSynchronizedGroups } public required init(from decoder: Decoder) throws { @@ -160,12 +176,21 @@ public class PBXTarget: PBXContainerItem { } else { productReference = nil } - - let packageProductDependencyReferenceStrings: [String] = try container.decodeIfPresent(.packageProductDependencies) ?? [] - packageProductDependencyReferences = packageProductDependencyReferenceStrings.map { - objectReferenceRepository.getOrCreate(reference: $0, objects: objects) + let packageProductDependencyReferenceStrings: [String]? = try container.decodeIfPresent(.packageProductDependencies) + if let packageProductDependencyReferenceStrings { + packageProductDependencyReferences = packageProductDependencyReferenceStrings.map { + objectReferenceRepository.getOrCreate(reference: $0, objects: objects) + } + } else { + packageProductDependencyReferences = nil } + let fileSystemSynchronizedGroupsReferences: [String]? = try container.decodeIfPresent(.fileSystemSynchronizedGroups) + if let fileSystemSynchronizedGroupsReferences { + self.fileSystemSynchronizedGroupsReferences = fileSystemSynchronizedGroupsReferences.map { + objectReferenceRepository.getOrCreate(reference: $0, objects: objects) + } + } productType = try container.decodeIfPresent(.productType) try super.init(from: decoder) } @@ -190,6 +215,13 @@ public class PBXTarget: PBXContainerItem { } dictionary["dependencies"] = .array(dependencyReferences.map { .string(CommentedString($0.value, comment: PBXTargetDependency.isa)) }) + if let fileSystemSynchronizedGroupsReferences { + dictionary["fileSystemSynchronizedGroups"] = .array(fileSystemSynchronizedGroupsReferences.map { fileSystemSynchronizedGroupReference in + let fileSystemSynchronizedGroup: PBXFileSystemSynchronizedRootGroup? = fileSystemSynchronizedGroupReference.getObject() + return .string(CommentedString(fileSystemSynchronizedGroupReference.value, comment: fileSystemSynchronizedGroup?.path)) + }) + } + dictionary["name"] = .string(CommentedString(name)) if let productName { dictionary["productName"] = .string(CommentedString(productName)) @@ -201,11 +233,12 @@ public class PBXTarget: PBXContainerItem { let fileElement: PBXFileElement? = productReference.getObject() dictionary["productReference"] = .string(CommentedString(productReference.value, comment: fileElement?.fileName())) } - if !packageProductDependencies.isEmpty { + if let packageProductDependencies { dictionary["packageProductDependencies"] = .array(packageProductDependencies.map { PlistValue.string(.init($0.reference.value, comment: $0.productName)) }) } + return (key: CommentedString(reference, comment: name), value: .dictionary(dictionary)) } diff --git a/Sources/XcodeProj/Utils/ReferenceGenerator.swift b/Sources/XcodeProj/Utils/ReferenceGenerator.swift index 823c582b..a098c829 100644 --- a/Sources/XcodeProj/Utils/ReferenceGenerator.swift +++ b/Sources/XcodeProj/Utils/ReferenceGenerator.swift @@ -100,7 +100,7 @@ final class ReferenceGenerator: ReferenceGenerating { identifiers.append(target.name) // Packages - for packageProductDependency in target.packageProductDependencies { + target.packageProductDependencies?.forEach { packageProductDependency in var identifiers = identifiers identifiers.append(packageProductDependency.productName) fixReference(for: packageProductDependency, identifiers: identifiers) diff --git a/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet+Fixtures.swift b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet+Fixtures.swift new file mode 100644 index 00000000..17e0b1f0 --- /dev/null +++ b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet+Fixtures.swift @@ -0,0 +1,17 @@ +import XcodeProj + +extension PBXFileSystemSynchronizedBuildFileExceptionSet { + static func fixture(target: PBXTarget = .fixture(), + membershipExceptions: [String]? = [], + publicHeaders: [String]? = [], + privateHeaders: [String]? = [], + additionalCompilerFlagsByRelativePath: [String: String]? = nil, + attributesByRelativePath: [String: [String]]? = nil) -> PBXFileSystemSynchronizedBuildFileExceptionSet { + PBXFileSystemSynchronizedBuildFileExceptionSet(target: target, + membershipExceptions: membershipExceptions, + publicHeaders: publicHeaders, + privateHeaders: privateHeaders, + additionalCompilerFlagsByRelativePath: additionalCompilerFlagsByRelativePath, + attributesByRelativePath: attributesByRelativePath) + } +} diff --git a/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSetTests.swift b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSetTests.swift new file mode 100644 index 00000000..84295484 --- /dev/null +++ b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSetTests.swift @@ -0,0 +1,29 @@ +import Foundation +import XCTest +@testable import XcodeProj + +final class PBXFileSystemSynchronizedBuildFileExceptionSetTests: XCTestCase { + var target: PBXTarget! + var subject: PBXFileSystemSynchronizedBuildFileExceptionSet! + + override func setUp() { + super.setUp() + target = PBXTarget.fixture() + subject = PBXFileSystemSynchronizedBuildFileExceptionSet.fixture(target: target) + } + + override func tearDown() { + target = nil + subject = nil + super.tearDown() + } + + func test_itHasTheCorrectIsa() { + XCTAssertEqual(PBXFileSystemSynchronizedBuildFileExceptionSet.isa, "PBXFileSystemSynchronizedBuildFileExceptionSet") + } + + func test_equal_returnsTheCorrectValue() { + let another = PBXFileSystemSynchronizedBuildFileExceptionSet.fixture(target: target) + XCTAssertEqual(subject, another) + } +} diff --git a/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroup+Fixtures.swift b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroup+Fixtures.swift new file mode 100644 index 00000000..c4eabf4f --- /dev/null +++ b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroup+Fixtures.swift @@ -0,0 +1,27 @@ +import XcodeProj + +extension PBXFileSystemSynchronizedRootGroup { + static func fixture(sourceTree: PBXSourceTree? = nil, + path: String? = nil, + name: String? = nil, + includeInIndex: Bool? = nil, + usesTabs: Bool? = nil, + indentWidth: UInt? = nil, + tabWidth: UInt? = nil, + wrapsLines: Bool? = nil, + explicitFileTypes: [String: String] = [:], + exceptions: [PBXFileSystemSynchronizedBuildFileExceptionSet] = [], + explicitFolders: [String] = []) -> PBXFileSystemSynchronizedRootGroup { + PBXFileSystemSynchronizedRootGroup(sourceTree: sourceTree, + path: path, + name: name, + includeInIndex: includeInIndex, + usesTabs: usesTabs, + indentWidth: indentWidth, + tabWidth: tabWidth, + wrapsLines: wrapsLines, + explicitFileTypes: explicitFileTypes, + exceptions: exceptions, + explicitFolders: explicitFolders) + } +} diff --git a/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroupTests.swift b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroupTests.swift new file mode 100644 index 00000000..37415610 --- /dev/null +++ b/Tests/XcodeProjTests/Objects/Files/PBXFileSystemSynchronizedRootGroupTests.swift @@ -0,0 +1,51 @@ +import Foundation +import XCTest +@testable import XcodeProj + +final class PBXFileSystemSynchronizedRootGroupTests: XCTestCase { + var subject: PBXFileSystemSynchronizedRootGroup! + var target: PBXTarget! + var exception: PBXFileSystemSynchronizedBuildFileExceptionSet! + + override func setUp() { + super.setUp() + target = PBXTarget.fixture() + exception = PBXFileSystemSynchronizedBuildFileExceptionSet.fixture(target: target) + subject = PBXFileSystemSynchronizedRootGroup(sourceTree: .group, + path: "synchronized", + name: "synchronized", + includeInIndex: true, + usesTabs: true, + indentWidth: 2, + tabWidth: 2, + wrapsLines: true, + explicitFileTypes: ["Source.m": "sourcecode.c.objc"], + exceptions: [exception], + explicitFolders: []) + } + + override func tearDown() { + exception = nil + subject = nil + super.tearDown() + } + + func test_itHasTheCorrectIsa() { + XCTAssertEqual(PBXFileSystemSynchronizedRootGroup.isa, "PBXFileSystemSynchronizedRootGroup") + } + + func test_equal_returnsTheCorrectValue() { + let another = PBXFileSystemSynchronizedRootGroup(sourceTree: .group, + path: "synchronized", + name: "synchronized", + includeInIndex: true, + usesTabs: true, + indentWidth: 2, + tabWidth: 2, + wrapsLines: true, + explicitFileTypes: ["Source.m": "sourcecode.c.objc"], + exceptions: [exception], + explicitFolders: []) + XCTAssertEqual(subject, another) + } +} diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift index d60e0838..9ff5e3cb 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift @@ -285,6 +285,38 @@ class PBXProjEncoderTests: XCTestCase { lines.validate(line: ");", after: line) } + // MARK: - File system synchronized root groups + + func test_fileSystemSynchronizedRootGroups_when_projectWithFileSystemSynchronizedRootGroups() throws { + // Given + try loadSynchronizedRootGroups() + let settings = PBXOutputSettings(projNavigatorFileOrder: .byFilenameGroupsFirst) + let lines = lines(fromFile: encodeProject(settings: settings)) + + let beginGroup = lines.findLine("/* Begin PBXFileSystemSynchronizedRootGroup section */") + var line = lines.validate(line: "6CF05B9D2C53F64800EF267F /* SynchronizedRootGroups */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (6CF05BA32C53F97F00EF267F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SynchronizedRootGroups; sourceTree = \"\"; };", after: beginGroup) + line = lines.validate(line: "/* End PBXFileSystemSynchronizedRootGroup section */", after: line) + } + + // MARK: - File system synchronized build file exception set + + func test_fileSystemSynchronizedBuildFileExceptionSets_when_projectWithFileSystemSynchronizedRootGroups() throws { + // Given + try loadSynchronizedRootGroups() + let settings = PBXOutputSettings(projNavigatorFileOrder: .byFilenameGroupsFirst) + let lines = lines(fromFile: encodeProject(settings: settings)) + + let beginGroup = lines.findLine("/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */") + var line = lines.validate(line: "6CF05BA32C53F97F00EF267F /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {", after: beginGroup) + line = lines.validate(line: "isa = PBXFileSystemSynchronizedBuildFileExceptionSet;", after: line) + line = lines.validate(line: "membershipExceptions = (", after: line) + line = lines.validate(line: "Exception/Exception.swift,", after: line) + line = lines.validate(line: ");", after: line) + line = lines.validate(line: "target = 6CF05B8B2C53F5F200EF267F /* SynchronizedRootGroups */;", after: line) + line = lines.validate(line: "};", after: line) + line = lines.validate(line: "/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */", after: line) + } + // MARK: - Build phases func test_build_phase_sources_unsorted_when_iOSProject() throws { @@ -457,6 +489,10 @@ class PBXProjEncoderTests: XCTestCase { proj = try PBXProj(jsonDictionary: iosProjectDictionary().1) } + private func loadSynchronizedRootGroups() throws { + proj = try PBXProj(jsonDictionary: synchronizedRootGroupsFixture().1) + } + private func loadFileSharedAcrossTargetsProject() throws { proj = try PBXProj(jsonDictionary: fileSharedAcrossTargetsDictionary().1) } diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProjectTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXProjectTests.swift index f2b9e091..5a343bfe 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProjectTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProjectTests.swift @@ -67,7 +67,7 @@ final class PBXProjectTests: XCTestCase { // Then XCTAssertEqual(packageProduct, objects.buildFiles.first?.value.product) XCTAssertEqual(packageProduct, objects.swiftPackageProductDependencies.first?.value) - XCTAssertEqual(packageProduct, target.packageProductDependencies.first) + XCTAssertEqual(packageProduct, target.packageProductDependencies?.first) XCTAssertEqual(objects.fileReferences.first?.value.name, "Product") @@ -240,8 +240,8 @@ final class PBXProjectTests: XCTestCase { XCTAssertEqual(packageProduct, secondPackageProduct) XCTAssertEqual(packageProduct, thirdPackageProduct) XCTAssertEqual(project.remotePackages.count, 1) - XCTAssertEqual(target.packageProductDependencies.count, 2) - XCTAssertEqual(secondTarget.packageProductDependencies.count, 1) + XCTAssertEqual(target.packageProductDependencies?.count, 2) + XCTAssertEqual(secondTarget.packageProductDependencies?.count, 1) XCTAssertNotEqual(buildPhase.files?.first?.hashValue, secondBuildPhase.files?.first?.hashValue) XCTAssertEqual(objects.swiftPackageProductDependencies.count, 2) diff --git a/Tests/XcodeProjTests/Project/XcodeProjTests.swift b/Tests/XcodeProjTests/Project/XcodeProjIntegrationTests.swift similarity index 89% rename from Tests/XcodeProjTests/Project/XcodeProjTests.swift rename to Tests/XcodeProjTests/Project/XcodeProjIntegrationTests.swift index 424767ed..8bcb7258 100644 --- a/Tests/XcodeProjTests/Project/XcodeProjTests.swift +++ b/Tests/XcodeProjTests/Project/XcodeProjIntegrationTests.swift @@ -25,6 +25,11 @@ final class XcodeProjIntegrationTests: XCTestCase { initModel: XcodeProj.init(path:)) } + func test_read_write_produces_no_diff_when_synchronizedRootGroupsFixture() throws { + try testReadWriteProducesNoDiff(from: synchronizedRootGroupsFixturePath, + initModel: XcodeProj.init(path:)) + } + func test_initialize_PBXProj_with_data() throws { // Given let pbxprojPath = iosProjectPath + "project.pbxproj" @@ -90,4 +95,8 @@ final class XcodeProjIntegrationTests: XCTestCase { private var iosProjectPath: Path { fixturesPath() + "iOS/Project.xcodeproj" } + + private var synchronizedRootGroupsFixturePath: Path { + fixturesPath() + "SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj" + } } diff --git a/Tests/XcodeProjTests/Tests/Fixtures.swift b/Tests/XcodeProjTests/Tests/Fixtures.swift index 40cc343f..edb724a5 100644 --- a/Tests/XcodeProjTests/Tests/Fixtures.swift +++ b/Tests/XcodeProjTests/Tests/Fixtures.swift @@ -6,6 +6,11 @@ func fixturesPath() -> Path { Path(#file).parent().parent().parent().parent() + "Fixtures" } +func synchronizedRootGroupsFixture() -> (Path, [String: Any]) { + let iosProject = fixturesPath() + "SynchronizedRootGroups/SynchronizedRootGroups.xcodeproj/project.pbxproj" + return (iosProject, loadPlist(path: iosProject.string)!) +} + func iosProjectDictionary() -> (Path, [String: Any]) { let iosProject = fixturesPath() + "iOS/Project.xcodeproj/project.pbxproj" return (iosProject, loadPlist(path: iosProject.string)!) From dc0380c75a04a0288be080d7e3e6a95f2c9f1a46 Mon Sep 17 00:00:00 2001 From: Pedro Date: Sat, 10 Aug 2024 18:28:29 +0200 Subject: [PATCH 08/13] Fix linting workflow --- .../PBXFileSystemSynchronizedBuildFileExceptionSet.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift index 572380cf..4f363322 100644 --- a/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift +++ b/Sources/XcodeProj/Objects/Files/PBXFileSystemSynchronizedBuildFileExceptionSet.swift @@ -38,7 +38,12 @@ public class PBXFileSystemSynchronizedBuildFileExceptionSet: PBXObject, PlistSer // MARK: - Init - public init(target: PBXTarget, membershipExceptions: [String]?, publicHeaders: [String]?, privateHeaders: [String]?, additionalCompilerFlagsByRelativePath: [String: String]?, attributesByRelativePath: [String: [String]]?) { + public init(target: PBXTarget, + membershipExceptions: [String]?, + publicHeaders: [String]?, + privateHeaders: [String]?, + additionalCompilerFlagsByRelativePath: [String: String]?, + attributesByRelativePath: [String: [String]]?) { targetReference = target.reference self.membershipExceptions = membershipExceptions self.publicHeaders = publicHeaders From c30a845e6e710c23076819e3f0359d3404e2c408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era=20Buend=C3=ADa?= <663605+pepicrft@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:54:55 +0200 Subject: [PATCH 09/13] chore: disable the renovatebot dashboard (#840) --- renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 7066eafd..d64bfc86 100644 --- a/renovate.json +++ b/renovate.json @@ -1,7 +1,8 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:base" + "config:base", + ":disableDependencyDashboard" ], "packageRules": [ { From 59271822fc7ecfb178025ccd79fb51381d5fcb51 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:55:34 +0200 Subject: [PATCH 10/13] chore(deps): update dependency tuist to v4.23.0 (#839) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mise.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mise.toml b/.mise.toml index ec954e15..85845c09 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,4 +1,4 @@ [tools] swiftformat = "0.54.3" -tuist = "4.21.2" +tuist = "4.23.0" swiftlint = "0.55.1" From db97fede763d9c68e8d70bea52cf1261e4771853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era=20Buend=C3=ADa?= <663605+pepicrft@users.noreply.github.com> Date: Sun, 11 Aug 2024 19:01:35 +0200 Subject: [PATCH 11/13] chore: continuously release releasable changes (#842) * Add continuous release * Generate the changelog from version 8.22.0 --- .github/workflows/conventional-pr.yml | 18 + .github/workflows/release.yml | 90 ++ .mise.toml | 1 + CHANGELOG.md | 1089 +------------------------ cliff.toml | 111 +++ 5 files changed, 234 insertions(+), 1075 deletions(-) create mode 100644 .github/workflows/conventional-pr.yml create mode 100644 .github/workflows/release.yml create mode 100644 cliff.toml diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml new file mode 100644 index 00000000..c145cda3 --- /dev/null +++ b/.github/workflows/conventional-pr.yml @@ -0,0 +1,18 @@ +name: conventional-pr +on: + pull_request: + branches: + - main + - master + types: + - opened + - edited + - synchronize +jobs: + lint-pr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: CondeNast/conventional-pull-request-action@v0.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..a4f0bf4c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,90 @@ +name: Release + +on: + push: + branches: + - main + workflow_dispatch: + inputs: + version: + description: 'The version to release' + type: string + +permissions: + contents: write + pull-requests: read + statuses: write + packages: write + +jobs: + release: + name: Release + runs-on: 'ubuntu-latest' + timeout-minutes: 15 + if: "!startsWith(github.event.head_commit.message, '[Release]')" + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + fetch-depth: 0 + - uses: jdx/mise-action@v2 + with: + experimental: true + - name: Check if there are releasable changes + id: is-releasable + run: | + # Run git cliff and save the output + bumped_output=$(git cliff 8.22.0.. --bump) + echo "Bumped output:" + echo "${bumped_output}" + + # Read the content of CHANGELOG.md + changelog_content=$(cat CHANGELOG.md) + echo "CHANGELOG.md content:" + echo "${changelog_content}" + + # Compare the outputs and set the result + if [ "${bumped_output}" = "${changelog_content}" ]; then + echo "should-release=false" >> $GITHUB_ENV + else + echo "should-release=true" >> $GITHUB_ENV + fi + + - name: Get next version + id: next-version + if: env.should-release == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: echo "NEXT_VERSION=$(git cliff 8.22.0.. --bumped-version)" >> "$GITHUB_OUTPUT" + - name: Get release notes + id: release-notes + if: env.should-release == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "RELEASE_NOTES<> "$GITHUB_OUTPUT" + git cliff 8.22.0.. --unreleased >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + - name: Update CHANGELOG.md + if: env.should-release == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: git cliff 8.22.0.. --bump -o CHANGELOG.md + - name: Commit changes + id: auto-commit-action + uses: stefanzweifel/git-auto-commit-action@v5 + if: env.should-release == 'true' + with: + commit_options: '--allow-empty' + tagging_message: ${{ steps.next-version.outputs.NEXT_VERSION }} + skip_dirty_check: true + commit_message: "[Release] XcodeProj ${{ steps.next-version.outputs.NEXT_VERSION }}" + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + if: env.should-release == 'true' + with: + draft: false + repository: tuist/XcodeProj + name: ${{ steps.next-version.outputs.NEXT_VERSION }} + tag_name: ${{ steps.next-version.outputs.NEXT_VERSION }} + body: ${{ steps.release-notes.outputs.RELEASE_NOTES }} + target_commitish: ${{ steps.auto-commit-action.outputs.commit_hash }} diff --git a/.mise.toml b/.mise.toml index 85845c09..5e6041a4 100644 --- a/.mise.toml +++ b/.mise.toml @@ -2,3 +2,4 @@ swiftformat = "0.54.3" tuist = "4.23.0" swiftlint = "0.55.1" +"git-cliff" = "2.4.0" diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d2ecce..71ffcc40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,1082 +1,21 @@ -🚀 Check out the guidelines [here](https://tuist.io/docs/contribution/changelog-guidelines/) +# Changelog -## Unreleased +All notable changes to this project will be documented in this file. -## 8.22.0 +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -### Added -* Add `buildArchitectures` to XCScheme+BuildAction by @woin2ee in https://github.com/tuist/XcodeProj/pull/824 +## [Unreleased] +### Details +#### Chore +- Set up SwiftLint and SwiftFormat, run them against the project, and run them as part of the CI workflows by @pepicrft in [#836](https://github.com/tuist/XcodeProj/pull/836) -### Changed -* Update comment to reflect productNameWithExtension() and others by @mikeger in https://github.com/tuist/XcodeProj/pull/823 +#### Docs +- Add filipracki as a contributor for code by @allcontributors[bot] in [#832](https://github.com/tuist/XcodeProj/pull/832) -## 8.21.0 +#### Feat +- Introduce the new Xcode 16 models `PBXFileSystemSynchronizedRootGroup` and `PBXFileSystemSynchronizedBuildFileExceptionSet` by @pepicrft in [#827](https://github.com/tuist/XcodeProj/pull/827) -### Fixed -* Fix package manifest by @0111b in https://github.com/tuist/XcodeProj/pull/816 +[unreleased]: https://github.com/tuist/XcodeProj/compare/8.22.0..HEAD -### Added -* Add Privacy Manifest in 'Projects Using' README table by @stelabouras in https://github.com/tuist/XcodeProj/pull/819 - -### Changed -* Adopt Strict Concurrency checking by @waltflanagan in https://github.com/tuist/XcodeProj/pull/821 -* Set minimum swift version to 5.8 by @waltflanagan in https://github.com/tuist/XcodeProj/pull/822 - -## 8.20.0 - -### Fixed -* Fix deprecation warning when targeting macOS 13 by @jszumski in https://github.com/tuist/XcodeProj/pull/814 - -## 8.19.0 - -### Added - -* Add precompiled header extension to headersExtensions for adding .pch… by @VorkhlikArtem in https://github.com/tuist/XcodeProj/pull/812 - -## 8.18.0 - -### Added -* Add `showNonLocalizedStrings` option to XCScheme+LaunchAction by @ladislas in https://github.com/tuist/XcodeProj/pull/806 -* Fix issue that it is not possible to remove a remote package by @kevin-kp in https://github.com/tuist/XcodeProj/pull/803 -* XCScheme string initializer by @mattmassicotte in https://github.com/tuist/XcodeProj/pull/809 - -### Changed -* Inherit values in the default `SWIFT_ACTIVE_COMPILATION_CONDITIONS` value by @pepicrft in https://github.com/tuist/XcodeProj/pull/811 - -## 8.17.0 - -### Added - -* Fix issue that it is not possible to remove a remote package by @kevin-kp in https://github.com/tuist/XcodeProj/pull/803 - -## 8.16.0 - -### Added - -* Create `PBXProj` class from the Data reprentation of a `pbxproj` file by @Ibrahimhass in https://github.com/tuist/XcodeProj/pull/798 -* Add XCLocalSwiftPackageReference Support by @art-divin in https://github.com/tuist/XcodeProj/pull/799 - -### Fixed - -* Fix issue that multiple products of the same package cannot be added by @kevin-kp in https://github.com/tuist/XcodeProj/pull/801 - -## 8.15.1 - -### Added - -- Added XCLocalSwiftPackageReference Support (#799)[https://github.com/tuist/XcodeProj/pull/799] by [@art-divin](https://github.com/art-divin). - -## 8.15.0 - -### Added - -- Added preferredScreenCaptureFormat to XCScheme.TestAcion [#792](https://github.com/tuist/XcodeProj/pull/792) by [@tatagrigory](https://github.com/tatagrigory). - - -## 8.14.0 - -### Added - -- Add otf font files to known file types [#788](https://github.com/tuist/XcodeProj/pull/788) by[@kwridan](https://github.com/kwridan) -- Get Data representation for `Writable` [#787](https://github.com/tuist/XcodeProj/pull/787) by [@Ibrahimhass](https://github.com/Ibrahimhass) - -## 8.13.0 - -### Added - -- Added `Build Tool Plug-ins` support [#784](https://github.com/tuist/XcodeProj/pull/784) by [@BarredEwe](https://github.com/BarredEwe) - -## 8.12.0 - -### Added - -- `PBXBuildRule.dependencyFile` attribute [#781](https://github.com/tuist/XcodeProj/pull/781) by [@pepicrft](https://github.com/pepicrft). -- Update last known `upgradeCheck` and `swiftUpgradeCheck` constants [#781](https://github.com/tuist/XcodeProj/pull/781) by [@pepicrft](https://github.com/pepicrft). -- Add the defaults `xcschemeFormatVersion`, `lastSwiftUpgradeCheck`, and `lastUpgradeCheck` [#781](https://github.com/tuist/XcodeProj/pull/781) by [@pepicrft](https://github.com/pepicrft). - -## 8.11.0 - -### Added - -- Support for Xcode runtime issue breakpoints [#761](https://github.com/tuist/XcodeProj/pull/761) by [@zenangst](https://github.com/zenangst). -- `Platform.visionOS` case and updated `BuildSettingsProvider` to return the default build settings for visionOS projects [#765](https://github.com/tuist/XcodeProj/pull/765) by [@Mstrodl](https://github.com/Mstrodl). - -### Changed - -- [PathKit](https://github.com/kylef/PathKit) version to [1.0.1](https://github.com/kylef/PathKit/blob/HEAD/CHANGELOG.md#%E2%80%8B101-2021-09-22). -- Bump `xcodeproj.podspec` macOS deployment target to 10.13. - -### Removed - -- **(Breaking)** Dropped [Carthage](https://github.com/Carthage/Carthage) support: Since the tool is not actively maintained. -- **(Breaking)** Dropped CocoaPods support: With the Apple ecosystem moving to Swift Package Manager we'd like to support the transition by dropping support for CocoaPods. The drop will simplify our release process. - -### Fixed - -- Ensured UUIDs are considered when sorting by filename to ensure information is not lost when filenames are equal [#769](https://github.com/tuist/XcodeProj/pull/769) by [@timothycosta](https://github.com/timothycosta). - -## 8.10.0 - -### Added - -- Add try-catch to getting started documentation [#745](https://github.com/tuist/XcodeProj/pull/745) by [@AlexKobachiJP](https://github.com/AlexKobachiJP) -- Add missing Build Settings Provider documentation [#747](https://github.com/tuist/XcodeProj/pull/747) by [@baekteun](https://github.com/baekteun) - -### Fixed - -- Fix unstable reads for `XCSchemeManagement` [#758](https://github.com/tuist/XcodeProj/pull/758) by [@kwridan](https://github.com/kwridan) -- Fix typos in `Writable.swift` [#755](https://github.com/tuist/XcodeProj/pull/755) by [@jpsim](https://github.com/jpsim) - -### Changed - -- Update `XCSharedData` Writable conformance to include `WorkspaceSettings` [#743](https://github.com/tuist/XcodeProj/pull/743) by [@dayton-bobbitt](https://github.com/dayton-bobbitt) - -## 8.9.0 - -### Added - -- Update watchOS application default settings for Xcode 14 [#711](https://github.com/tuist/XcodeProj/pull/711) by [@kwridan](https://github.com/kwridan) -- Implement `Hashable` for `XCScheme.BuildableReference` [#712](https://github.com/tuist/XcodeProj/pull/712) by [@cgrindel](https://github.com/cgrindel) -- Sets customWorkingDirectory for schemes [#720](https://github.com/tuist/XcodeProj/pull/720) by [@maxwellE](https://github.com/maxwellE) -- Add `XCScheme.ExecutionAction.shellToInvoke` [#721](https://github.com/tuist/XcodeProj/pull/721) by [@CrazyFanFan](https://github.com/CrazyFanFan) -- Add `platformFilters` attribute to `PBXBuildFile` and `PBXTargetDependency` [#737](https://github.com/tuist/XcodeProj/pull/737) by [@maxwellE](https://github.com/maxwellE) -- Add suppot for `XCUserData` [#739](https://github.com/tuist/XcodeProj/pull/739) by [@teameh](https://github.com/teameh) - -## 8.8.0 - -### Fixed - -- Fix equality checking of dictionaries [#667](https://github.com/tuist/XcodeProj/pull/667) by [@brentleyjones](https://github.com/brentleyjones) -- Quiet new warnings from Xcode 13.3 [#673](https://github.com/tuist/XcodeProj/pull/673) by [@hisaac](https://github.com/hisaac) -- Fix typo in PBXOutputSettings.swift [#678](https://github.com/tuist/XcodeProj/pull/678) by [@eltociear](https://github.com/eltociear) -- Fix syntax error in docs [#679](https://github.com/tuist/XcodeProj/pull/679) by [@maxwellE](https://github.com/maxwellE) -- Misspelling in comment [#680](https://github.com/tuist/XcodeProj/pull/680) by [@maxwellE](https://github.com/maxwellE) -- Misspelling in comment [#681](https://github.com/tuist/XcodeProj/pull/681) by [@maxwellE](https://github.com/maxwellE) -- Ensure correct `LaunchAction` scheme order [#686](https://github.com/tuist/XcodeProj/pull/686) by [@maxwellE](https://github.com/maxwellE) -- Fix TestAction scheme attribute ordering [#689](https://github.com/tuist/XcodeProj/pull/689) by [@maxwellE](https://github.com/maxwellE) -- Fix `Testables` element ordering [#702](https://github.com/tuist/XcodeProj/pull/702) by [@maxwellE](https://github.com/maxwellE) -- Fix `RemoteRunnable` scheme attr order [#701](https://github.com/tuist/XcodeProj/pull/701) by [@maxwellE](https://github.com/maxwellE) -- Fix ordering of Scheme toplevel attrs [#698](https://github.com/tuist/XcodeProj/pull/698) by [@maxwellE](https://github.com/maxwellE) -- Fix order for `askForAppToLaunch` attr [#705](https://github.com/tuist/XcodeProj/pull/705) by [@maxwellE](https://github.com/maxwellE) -- Fix ordering of diagnostics scheme options [#704](https://github.com/tuist/XcodeProj/pull/704) by [@kwridan](https://github.com/kwridan) - -### Added - -- Add `addDependency()` helper method to `PBXAggregateTarget` [#677](https://github.com/tuist/XcodeProj/pull/677) by [@brentleyjones](https://github.com/brentleyjones) -- Allow for initializing a PBXProj via a direct path [#682](https://github.com/tuist/XcodeProj/pull/682) by [@maxwellE](https://github.com/maxwellE) -- Add `.extensionKitExtension` as the new `PBXProductType` [#691](https://github.com/tuist/XcodeProj/pull/691) by [@mtj0928](https://github.com/mtj0928) -- Added `disablePerformanceAntipatternChecker` to `XCScheme` [#693](https://github.com/tuist/XcodeProj/pull/603) by [@Bogdan-Belogurov](https://github.com/Bogdan-Belogurov) -- Added missing `askForAppToLaunch` in `ProfileAction` [#700](https://github.com/tuist/XcodeProj/pull/700) by [@maxwellE](https://github.com/maxwellE) -- Add `launchAutomaticallySubstyle`->`ProfileAction` [#699](https://github.com/tuist/XcodeProj/pull/699) by [@maxwellE](https://github.com/maxwellE) -- Add `DEAD_CODE_STRIPPING` default project setting [#706](https://github.com/tuist/XcodeProj/pull/706) by [@kwridan](https://github.com/kwridan) - -### Changed - -- Use `Runnable` in `ProfileAction` [#703](https://github.com/tuist/XcodeProj/pull/703) by [@maxwellE](https://github.com/maxwellE) - -## 8.7.1 - -### Changed -- Make WorkspaceSettings initializer public [#658](https://github.com/tuist/XcodeProj/pull/658) by [@jakeatoms](https://github.com/jakeatoms) - -## 8.7.0 -### Added - -- Add DocC Xcode File Type (`.docc`) [#660](https://github.com/tuist/XcodeProj/pull/660) by [@Jake-Prickett](https://github.com/Jake-Prickett) - -## 8.6.0 -### Added - -- Support for location added to test targets (`TestableReference`) [#654](https://github.com/tuist/XcodeProj/pull/654) by [@KrisRJack](https://github.com/KrisRJack) - -## 8.5.0 - -### Added - -- Add XCSchemeManagement struct https://github.com/tuist/XcodeProj/pull/565 by @pepibumur. - -### Changed -- Update the last-known and default constants to align with Xcode 13. - -## 8.4.0 -### Added - -- Support customized DerrivedData path in `WorkspaceSettings` [#650](https://github.com/tuist/XcodeProj/pull/650) by [@freddi-kit](https://github.com/freddi-kit). - -### 8.3.1 -### Fixed - -- Fix Xcode 13 build [#648](https://github.com/tuist/XcodeProj/pull/648) by [@raptorxcz](https://github.com/raptorxcz) - -## 8.3.0 - Mojo -### Added - -- `CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED` to default build setting [#641](https://github.com/tuist/XcodeProj/pull/641) by [@flowbe](https://github.com/flowbe) - -### Fixed - -- Xcode 13 build issues [#646](https://github.com/tuist/XcodeProj/pull/646) by [@jsorge](https://github.com/jsorge) - -## 8.2.0 - Bubbles -### Added - -- Support obtaining the full path of a file element by passing the source root as a string [#624](https://github.com/tuist/XcodeProj/pull/624) by [@ileitch](https://github.com/ileitch). - -### Fixed - -- If RemoteRunnable doesn't contains BuildableReference XcodeProj removes xcscheme file [#627](https://github.com/tuist/XcodeProj/pull/627) by [@subdan](https://github.com/subdan). - -### Changed - -- Updated AEXML to 4.6.1 [#632](https://github.com/tuist/XcodeProj/pull/632) by [@nnsnodnb](https://github.com/nnsnodnb). -## 8.1.0 - Barcelona -### Changed - -- Improve performance of commented string [#635](https://github.com/tuist/XcodeProj/pull/635) by [@adellibovi](https://github.com/adellibovi) - -## 8.0.0 - Amor -### Fixed - -- Adding group set incorrect parent in case of complex path [#614](https://github.com/tuist/XcodeProj/pull/614) by [@avdyushin](https://github.com/avdyushin) -- **Breaking** Fixed issue where some schemes could not be deserialized because a buildable reference did not contain a blueprint identifier [#612](https://github.com/tuist/XcodeProj/pull/612) by [@daltonclaybrook](https://github.com/daltonclaybrook) -- Added the `com.apple.product-type.driver-extension` and `com.apple.product-type.system-extension` PBXProductType [#618](https://github.com/tuist/XcodeProj/pull/618) by [@vgorloff](https://github.com/vgorloff). - -### Changed - -- **Breaking** Make `runPostActionsOnFailure` optional [#619](https://github.com/tuist/XcodeProj/pull/619) by [@kwridan](https://github.com/kwridan) - -## 7.23.0 - Bonsai -### Added - -- Allows passing BuildableIdentifier String to BuildableReference initializer [#605](https://github.com/tuist/XcodeProj/pull/605) by [@freddi-kit](https://github.com/freddi-kit) - -### Fixed - -- Fixed building on Linux [#615](https://github.com/tuist/XcodeProj/pull/615) by [@yonaskolb](https://github.com/yonaskolb) - -## 7.22.0 - Ringui Dingui - -### Added - -- `CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER` to default build setting [#608](https://github.com/tuist/XcodeProj/pull/608) by [@fortmarek](https://github.com/fortmarek) - -### Fixed - -- Prevent overwriting identical workspace data [#607](https://github.com/tuist/XcodeProj/pull/607) by [@ferologics](https://github.com/ferologics) - -## 7.21.0 - Alfredo - -### Changed - -- Speed up md5 generation [#606](https://github.com/tuist/XcodeProj/pull/606) by [@adellibovi](https://github.com/adellibovi) - -## 7.20.0 - Sol - -### Added - -- Added `runPostActionsOnFailure` to `XCScheme` [#603](https://github.com/tuist/XcodeProj/pull/603) by [@FranzBusch](https://github.com/FranzBusch) - -## 7.19.0 - Kreuzberg - -### Fixed - -- JSON decoder not properly decoding `defaultConfigurationIsVisible` in some projects [#593](https://github.com/tuist/XcodeProj/pull/593) by [@tjwio](https://github.com/tjwio) -- JSON decoder not properly decoding `proxyType` in some projects [#596](https://github.com/tuist/XcodeProj/issues/596) by [@tjwio](https://github.com/tjwio) -- BuildPhaseTests not handling failure cases properly [#597](https://github.com/tuist/XcodeProj/issues/597) by [@tjwio](https://github.com/tjwio) -- `xcconfig` parser does not support inline comments [#602](https://github.com/tuist/XcodeProj/issues/602) by [@dive](https://github.com/dive) - -## 7.18.0 - Penguin - -### Added - -- Support for building and running on Linux. [#585](https://github.com/tuist/XcodeProj/pull/585) by [@elliottwilliams](https://github.com/elliottwilliams). -- Tested for compatibility with Swift 5.3 on Ubuntu 18.04. -- XcodeProj requires FoundationXML / libxml2, which is part of the standard Swift Linux toolchain but not necessarily available in all environments. - -## 7.17.0 - Tempelhof - -### Added - -- Added the `com.apple.product-type.metal-library` PBXProductType [#576](https://github.com/tuist/XcodeProj/pull/576) by [@deatondg](https://github.com/deatondg). -- Deprecate PBXBuildPhase.type() function https://github.com/tuist/XcodeProj/pull/571 by [@marciniwanicki](https://github.com/marciniwanicki). -- Added `runOncePerArchitecture` attribute to `PBXBuildRule` https://github.com/tuist/XcodeProj/pull/570 by @sascha - -## 7.16.0 - Cieza - -### Added - -- Set the right `module_name` in the `.podspec.` [#578](https://github.com/tuist/XcodeProj/pull/578) by [@dflems](https://github.com/dflems). - -## 7.15.0 - Marea - -### Fixed - -- explicitFileType corrected for .bundle https://github.com/tuist/XcodeProj/pull/563 by @adamkhazi - -### Added - -- Add support for alwaysOutOfDate flag in PBXShellScriptBuildPhase https://github.com/tuist/XcodeProj/pull/572 by @marciniwanicki -- Added `PBXShellScriptBuildPhase.dependencyFile` attribute https://github.com/tuist/xcodeproj/pull/568 by @polac24 -- Add support for StoreKitConfigurationFileReference in LaunchAction of XCScheme https://github.com/tuist/XcodeProj/pull/573 by @jcolicchio - -## 7.14.0 - -### Fixed - -- lastKnownFileType for .ttf and .sqlite files https://github.com/tuist/XcodeProj/pull/557 by @adamkhazi - -### Added - -- Added selectedTests attribute to XCScheme.TestableReference https://github.com/tuist/XcodeProj/pull/559 by @ooodin - -## 7.13.0 - -### Added - -- Support `on-demand-install-capable` application https://github.com/tuist/XcodeProj/pull/554 by @d-date -- Add RemotePath to RemoteRunnable https://github.com/tuist/XcodeProj/pull/555 by @kwridan - -## 7.12.0 - -### Added - -- Added `LaunchAction.customLLDBInitFile` and `TestAction.customLLDBInitFile` attributes https://github.com/tuist/xcodeproj/pull/553 by @polac24 - -## 7.11.1 - -### Added - -- Added `platformFilter` to the `PBXTargetDependency` https://github.com/tuist/XcodeProj/pull/546 by @tomaslinhart - -## 7.11.0 - -### Changed - -- Point `XcodeProjCExt` to version 0.1.0 https://github.com/tuist/XcodeProj/pull/540 by @khoi - -### Added - -- Added `useTestSelectionWhitelist` attribute to `XCScheme.TestableReference` https://github.com/tuist/xcodeproj/pull/516 by @basvankuijck. - -### Fixed - -- "Products" group has the same ID for any project https://github.com/tuist/XcodeProj/issues/538 by @damirdavletov - -## 7.10.0 - -### Changed - -- Optimize bottlenecks https://github.com/tuist/XcodeProj/pull/529 by @michaeleisel - -## 7.9.0 - -### Changed - -- Remove `Tapestries` folder for tapestry 0.0.5 version https://github.com/tuist/XcodeProj/pull/523 by @fortmarek -- Sped up the generation of commented strings, especially those that include an MD5 hash - -### Fixed - -- Code Coverage Targets and Additional Options Scheme Instability https://github.com/tuist/XcodeProj/pull/522 by @adamkhazi -- Fix `XCWorkspace` `Equatable` https://github.com/tuist/XcodeProj/pull/524 by @adamkhazi - -## 7.8.0 - -### Added - -- Added `PathRunnable` to the `LaunchAction` to allow running any executable https://github.com/tuist/XcodeProj/pull/521 by @vytis - -### Fixed - -- Make `PBXProject.targetAttributes` non optional again and fix equality https://github.com/tuist/XcodeProj/pull/519 by @yonaskolb - -## 7.7.0 - -### Fixed - -- Ensure references to products in external projects are generated with deterministic UUIDs https://github.com/tuist/XcodeProj/pull/518 by @evandcoleman - -## 7.6.0 - -### Changed - -- **Breaking** Make `PBXProject.targetAttributes` optional https://github.com/tuist/XcodeProj/pull/517 by @pepibumur - -### Fixed - -- Remove "Shell" Carthage dependency from carthage xcode project as it's no longer used https://github.com/tuist/XcodeProj/pull/507 by @imben123 - -### Added - -- Added `com.apple.product-type.xcframework` to `PBXProductType`. https://github.com/tuist/XcodeProj/pull/508 by @lakpa -- Added `askForAppToLaunch` parameter to `LaunchAction` and `ProfileAction`. https://github.com/tuist/XcodeProj/pull/515 by @YutoMizutani -- Added `"ENABLE_PREVIEWS"` to target application build settings https://github.com/tuist/XcodeProj/pull/511 by @fortmarek - -## 7.5.0 - -### Fixed - -- Provide default build settings for unit and ui test targets https://github.com/tuist/XcodeProj/pull/501 by @kwridan -- Remove "Shell" Carthage dependency from project manifest as it's no longer used https://github.com/tuist/XcodeProj/pull/505 by @kwridan - -## 7.4.0 - -### Changed - -- Update list of recognized file extensions https://github.com/tuist/XcodeProj/pull/500 by @dflems - -## 7.3.0 - -### Changed - -- Update BuildSettingsProvider to include extension settings https://github.com/tuist/XcodeProj/pull/497 by @kwridan -- Remove the dependency with the Swift Package Manager https://github.com/tuist/XcodeProj/pull/499 by @elliottwilliams - -## 7.2.2 - -### Fixed - -- Make test plans deserialise correctly https://github.com/tuist/XcodeProj/pull/496 by @adamkhazi - -## 7.2.1 - -### Fixed - -- Make test plans optional https://github.com/tuist/XcodeProj/commit/c15034948a2a132bf559f14d3c6b4d1b73749663 by @pepibumur - -### Changed - -- Replaced CircleCI with GitHub actions https://github.com/tuist/XcodeProj/pull/493 by @pepibumur -- Replace CircleCI with GitHub actions https://github.com/tuist/XcodeProj/pull/493 by @pepibumur -- Replace Shell with the SPM's Process utility class https://github.com/tuist/XcodeProj/pull/492 by @pepibumur - -### Added - -- Automating release process with [tapestry](https://github.com/ackeecz/tapestry) https://github.com/tuist/XcodeProj/pull/495 by @fortmarek - -## 7.2.0 - -### Added - -- Added support for Xcode 11 test plans https://github.com/tuist/XcodeProj/pull/491 by @maniramezan - -### Fixed - -- Add remote Swift packages to the Frameworks build phase https://github.com/tuist/XcodeProj/pull/487 by @kwridan -- System library added to a group has empty path https://github.com/tuist/XcodeProj/pull/488 by @damirdavletov -- Fix Products group serialisation with temporary ids https://github.com/tuist/XcodeProj/pull/489 by @damirdavletov - -## 7.1.0 - -### Added - -- Add `onlyGenerateCoverageForSpecifiedTargets` parameter to `TestAction` https://github.com/tuist/XcodeProj/pull/473 by @kateinoigakukun -- Added support for `PBXTargetDependency.product` https://github.com/tuist/XcodeProj/pull/481 by @yonaskolb -- Xcode 11 support. - -## 7.0.1 - -### Changed - -- Update `BuildSettingProvider` to return `LD_RUNPATH_SEARCH_PATHS` as `Array` https://github.com/tuist/xcodeproj/pull/463 by @marciniwanicki -- Update `Project.swift` to make it compatible with tuist 0.17.0 https://github.com/tuist/xcodeproj/pull/469 by @marciniwanicki - -### Added - -- Adding support for adding local Swift packages https://github.com/tuist/XcodeProj/pull/468 by @fortmarek -- Adding additional `lastKnownFileType`s https://github.com/tuist/xcodeproj/pull/458 by @kwridan -- Adding possibility to create variant group for referencing localized resources https://github.com/tuist/xcodeproj/pull/462 by @timbaev - -### Fixed - -- Duplication of packages https://github.com/tuist/XcodeProj/pull/470 by @fortmarek - -## 7.0.0 - -### Changed - -- **Breaking** Change the UUID generation logic to generate ids with a length of 24 https://github.com/tuist/xcodeproj/pull/432 by @pepibumur. -- **Breaking** Renamed module from `xcodeproj` to `XcodeProj` https://github.com/tuist/xcodeproj/pull/398 by @pepibumur. -- Add `override` flag to `PBXGroup.addFile(at:,sourceTree:,sourceRoot:)` https://github.com/tuist/xcodeproj/pull/410 by @mrylmz -- Rename some internal variables to have a more representative name https://github.com/tuist/xcodeproj/pull/415 by @pepibumur. - -### Added - -- **Breaking** Add `SWIFT_COMPILATION_MODE` and `CODE_SIGN_IDENTITY` build settings, remove `DEBUG` flag for Release https://github.com/tuist/xcodeproj/pull/417 @dangthaison91 -- **Breaking** Added throwing an error in case group path can't be resolved by @damirdavletov -- **Breaking** Added remote project support to PBXContainerItemProxy by @damirdavletov -- **Breaking** Add support for `RemoteRunnable` https://github.com/tuist/xcodeproj/pull/400 by @pepibumur. -- **Breaking** Swift 5 support https://github.com/tuist/xcodeproj/pull/397 by @pepibumur. -- Added `com.apple.product-type.application.watchapp2-container` to `PBXProductType`. https://github.com/tuist/xcodeproj/pull/441 by @leogdion. -- Add BatchUpdater to quickly add files to the group https://github.com/tuist/xcodeproj/pull/388 by @CognitiveDisson. -- `WorkspaceSettings.autoCreateSchemes` attribute https://github.com/tuist/xcodeproj/pull/399 by @pepibumur -- Additional Swift 5 fixes: https://github.com/tuist/xcodeproj/pull/402 by @samisuteria -- Make build phase name public by @llinardos. -- Can access embed frameworks build phase for a target by @llinardos. -- Added `com.apple.product-type.framework.static` to `PBXProductType`. https://github.com/tuist/xcodeproj/pull/347 by @ileitch. -- Can add a not existing file to a group https://github.com/tuist/xcodeproj/pull/418 by @llinardos. -- Support for Swift PM Packages https://github.com/tuist/xcodeproj/pull/439 https://github.com/tuist/xcodeproj/pull/444 by @pepibumur @yonaskolb. -- `LaunchAction.customLaunchCommand` attribute https://github.com/tuist/xcodeproj/pull/451 by @pepibumur. -- `XCBuildConfiguration.append` method https://github.com/tuist/xcodeproj/pull/450 by @pepibumur. - -### Fixed - -- Carthage integration https://github.com/tuist/xcodeproj/pull/416 by @pepibumur. -- Relative path is wrong when referencing file outside of project folder https://github.com/tuist/xcodeproj/issues/423 by @damirdavletov -- [crash] Fatal error: Duplicate values for key https://github.com/tuist/xcodeproj/issues/426 by @toshi0383 -- Change PBXContainerItemProxy.remoteGlobalID attribute to support object references https://github.com/tuist/xcodeproj/pull/445 by @yonaskolb -- Dead lock in the `PBXObjects.delete` method https://github.com/tuist/xcodeproj/pull/449 by @pepibumur - -### Removed - -- OSLogs https://github.com/tuist/xcodeproj/pull/453 by @pepibumur. - -## 6.7.0 - -### Changed - -- **Breaking** Make `PBXBuildPhase.files` optional to match Xcode's behavior https://github.com/tuist/xcodeproj/pull/391 by @pepibumur. - -### Added - -- Add location variable to XCWorkspaceDataElement https://github.com/tuist/xcodeproj/pull/387 by @pepibumur. - -### Fixed - -- Fixed file full path performance issue https://github.com/tuist/xcodeproj/pull/372 by @CognitiveDisson. -- Diffing issues when writing the project https://github.com/tuist/xcodeproj/pull/391 by @pepibumur. - -## 6.6.0 - -### Fixed - -- Fix adding files to `PBXBuildPhase` https://github.com/tuist/xcodeproj/pull/380 @danilsmakotin. -- Improve project encoding performance https://github.com/tuist/xcodeproj/pull/371 by @CognitiveDisson. -- Project decoding performance issue https://github.com/tuist/xcodeproj/pull/365 by @CognitiveDisson. -- Fix PBXTarget extension methods https://github.com/tuist/xcodeproj/pull/367 by @danilsmakotin. - -### Added - -- Added `GPUFrameCaptureMode` and `GPUValidationMode` options to `LaunchAction` https://github.com/tuist/xcodeproj/pull/368 by @schiewe. -- Add Swiftformat https://github.com/tuist/xcodeproj/pull/375 by @pepibumur. - -### Changed - -- **Breaking** Rename GPUFrameCaptureMode cases to start with a lowercase letter https://github.com/tuist/xcodeproj/pull/375 by @pepibumur. -- Fix linting issues https://github.com/tuist/xcodeproj/pull/375 by @pepibumur. - -## 6.5.0 - -### Changed - -- Make Xcode.Supported.xcschemeFormatVersion public https://github.com/tuist/xcodeproj/pull/361 by @yonaskolb. - -### Added - -- Fix remote target dependency https://github.com/tuist/xcodeproj/pull/362 by @mxcl. - -## 6.4.0 - -### Added - -- Added `projReferenceFormat` to `PBXOutputSettings` to allow changing the output format of generated references. `withPrefixAndSuffix` will give the legacy behaviour `xcode` will generate 32 character references as XCode does. https://github.com/tuist/xcodeproj/pull/345 by @samskiter. -- Danger https://github.com/tuist/xcodeproj/pull/357 by @pepibumur. -- Support for WorkspaceSettings https://github.com/tuist/xcodeproj/pull/359 by @pepibumur. - -## 6.3.0 - -### Added - -- Added `parallelizable` and `randomExecutionOrdering` attributes to `XCScheme.TestableReference` https://github.com/tuist/xcodeproj/pull/340 by @alvarhansen. - -### Fixed - -- Fixed possible generated UUID conflicts https://github.com/tuist/xcodeproj/pull/342 by @yonaskolb. -- Fixed not working PBXFileElement.fullPath(sourceRoot:) method https://github.com/tuist/xcodeproj/pull/343 by @Vyeczorny. - -## 6.2.0 - -### Added - -- Carthage and CocoaPods support https://github.com/tuist/xcodeproj/pull/339 by @pepibumur. - -### Changed - -- Improved writing performance https://github.com/tuist/xcodeproj/pull/336 https://github.com/tuist/xcodeproj/pull/337 https://github.com/tuist/xcodeproj/pull/338 by @yonaskolb. -- Replaced Swift Package Manager dependency with PathKit https://github.com/tuist/xcodeproj/pull/334 by @yonaskolb. - -## 6.1.0 - -### Added - -- Added ability to pass in a `PBXObject` into the `PBXProject.targetAttributes` dictionary, which will be encoded into its UUID. Can be used for `TestTargetID` https://github.com/tuist/xcodeproj/pull/333 by @yonaskolb. - -### Changed - -- Changed `XCScheme.BuildableReference` init to make `blueprint` a `PBXObject` and added a `setBlueprint(:)` function https://github.com/tuist/xcodeproj/pull/320 by @yonaskolb. -- Bump AEXML version to 4.3.3 https://github.com/tuist/xcodeproj/pull/310 by @pepibumur. -- Improves performance of object references https://github.com/tuist/xcodeproj/pull/332 by @yonaskolb. -- Prefix reference with object type acronym. eg. `PBXFileReference` becomes `FR_XXXXXXXXXXXXXXXXX` https://github.com/tuist/xcodeproj/pull/332 by @yonaskolb. -- Add `TEMP` prefix to temporary unfixed reference values https://github.com/tuist/xcodeproj/pull/332 by @yonaskolb. - -### Fixed - -- Fixed written order of scheme attributes in Swift 4.2 https://github.com/tuist/xcodeproj/pull/325 and https://github.com/tuist/xcodeproj/pull/331 by @yonaskolb and @drekka - -## 6.0.1 - -### Fixed - -- Fixes `PBXProject` attributes not being set properly https://github.com/tuist/xcodeproj/pull/318 by @yonaskolb. -- Fixed remoteGlobalID typo https://github.com/tuist/xcodeproj/pull/315 by @yonaskolb. -- Fixed `XCBuildConfiguration.buildConfiguration` type https://github.com/tuist/xcodeproj/pull/316 by @yonaskolb. - -## 6.0.0 - -Note: Migration guidelines are included in the project README. - -### Changed - -- **Breaking** Make `PBXObjectReference` internal https://github.com/tuist/xcodeproj/pull/300 by @pepibumur. -- **Breaking** Make `PBXObjects` internal https://github.com/tuist/xcodeproj/pull/300 by @pepibumur. -- **Breaking** Move `PBXObjects` helpers to `PBXProj` https://github.com/tuist/xcodeproj/pull/300 by @pepibumur. - -## 5.2.0 - -### Changed - -- Some tweaks to support Xcode 10 https://github.com/tuist/xcodeproj/pull/298 by @pepibumur. - -## 5.1.1 - -### Changed - -- **Breaking** Change `PBXBuildFile.file` attribute to be of type `PBXFileElement` https://github.com/tuist/xcodeproj/pull/297 by @pepibumur. - -### Added - -- Add `PBXBuildPhase.add(file:)` method that takes a file element and returns a build file https://github.com/tuist/xcodeproj/pull/297 by @pepibumur. -- Add `PBXProj.rootObject` attribute https://github.com/tuist/xcodeproj/pull/297 by @pepibumur. - -### Fixed - -- `XCBuildConfiguration.baseConfiguration` type https://github.com/tuist/xcodeproj/pull/297 @pepibumur. - -## 5.1.0 - -### Added - -- `setAttributes`, `removeAttributes` and `attributes` to `PBXProject` https://github.com/tuist/xcodeproj/pull/295 by @pepibumur - -### Changed - -- **Breaking** Change `blueprintIdentifier` type to `PBXObjectReference` https://github.com/tuist/xcodeproj/pull/289 by @pepibumur - -### Fixed - -- Fix grammatical issues and add some convenient getters https://github.com/tuist/xcodeproj/pull/291 by @pepibumur -- Fix targets not getting the reference generated https://github.com/tuist/xcodeproj/pull/290 by @pepibumur -- Product references not being generated https://github.com/tuist/xcodeproj/pull/294 by @pepibumur - -### Removed - -- **Breaking** Make `PBXProject.attributes` internal https://github.com/tuist/xcodeproj/pull/295 by @pepibumur - -## 5.0.0 - -Nothing new since the release rc2. - -## 5.0.0-rc2 - -### Changed - -- **Breaking** Rename `filesReferences` to `fileReferences` https://github.com/tuist/xcodeproj/pull/271 by @pepibumur - -### Added - -- Xcode 10 inputFileListPaths and outputFileListPaths attributes https://github.com/tuist/xcodeproj/pull/271 by @pepibumur -- Split up `XCScheme` models and make them conform the `Equatable` protocol https://github.com/tuist/xcodeproj/pull/273 by @pepibumur -- Convenient methods to add and fetch build configurations https://github.com/tuist/xcodeproj/pull/283 by @pepibumur -- `.inc` extension to the header file extensions by @pepibumur - -## 5.0.0-rc1 - -### Breaking - -- Rename project to xcodeproj by @pepibumur. -- Drop Carthage and CocoaPods support by @pepibumur. -- Use Basic AbsolutePath, RelativePath and Process extensions by @pepibumur. -- Use `PBXObjectReference` instead of `String` to reference objects from `PBXProj.Objects` by @pepibumur. -- Remove `ObjectReference` by @pepibumur. -- Update `PBXNativeTarget` reference attributes to be of type `PBXObjectReference` by @pepibumur. -- Add convenient methods to materialize objects references https://github.com/tuist/xcodeproj/pull/12 by @pepibumur. -- Rename some PBXProject attributes for consistency https://github.com/tuist/xcodeproj/pull/268 by @pepibumur. - -### Added - -- Add `addDependency` method to `PBXNativeTarget` by @pepibumur. -- Danger check that reports Swiftlint results https://github.com/xcodeswift/xcproj/pull/257 by @pepibumur. -- Xcode constants by @pepibumur. -- Convenient API from objects by @pepibumur. -- `BuildSettingsProvider` by @pepibumur. -- Add `addDependency` method to `PBXNativeTarget` by @pepibumur. -- Method in `XCConfigurationList` to get the build configurations objects @pepibumur. -- Method to get the configuration list from any target https://github.com/tuist/xcodeproj/pull/10 by @pepibumur. -- Migration guidelines https://github.com/tuist/xcodeproj/pull/264 by @pepibumur. - -### Removed - -- Deprecated elements by @pepibumur. -- Tests that test the conformance of `Equatable` by @pepibumur. - -### Fixed - -- XCConfig parser strips the trailing semicolon from a configuration value https://github.com/xcodeswift/xcproj/pull/250 by @briantkelley -- `fullPath(fileElement:reference:sourceRoot:)` now returns the correct path for files that exist within a variant group https://github.com/xcodeswift/xcproj/pull/255 by @ileitch - -### Added - -- Update Danger to warn if the PR title contains WIP https://github.com/xcodeswift/xcproj/pull/259 by @pepibumur. -- Test coverage reports https://github.com/xcodeswift/xcproj/pull/258 by @pepibumur - -## 4.3.0 - -### Added - -- CI pipeline runs also on a Linux environment https://github.com/xcodeswift/xcproj/pull/249 by @pepibumur. -- Auto-generation of Equatable conformances using Sourcery https://github.com/xcodeswift/xcproj/pull/189 @by pepibumur. - -### Fixed - -- Some updates to match the Xcode 9.3 project format https://github.com/xcodeswift/xcproj/pull/247 by @LinusU - -## 4.2.0 - -### Added - -- `PBXNativeTarget.productInstallPath`, `PBXTargetDependency.name` https://github.com/xcodeswift/xcproj/pull/241 by @briantkelley -- `PBXContainerItem` super class of `PBXBuildPhase` and `PBXTarget` https://github.com/xcodeswift/xcproj/pull/243 by @briantkelley -- `PBXFileElement.wrapsLines`property https://github.com/xcodeswift/xcproj/pull/244 by @briantkelley -- `PBXFileReference` `languageSpecificationIdentifier` and `plistStructureDefinitionIdentifier` properties https://github.com/xcodeswift/xcproj/pull/244 by @briantkelley - -### Changed - -- Support for `XCConfig` project-relative includes https://github.com/xcodeswift/xcproj/pull/238 by @briantkelley -- Migrated `PBXProject.projectRoot` to `PBXProject.projectRoots` https://github.com/xcodeswift/xcproj/pull/242 by @briantkelley -- Moved `PBXFileElement.includeInIndex` and `PBXGroup`'s `usesTabs`, `indentWidth`, and `tabWidth` properties to `PBXFileElement` https://github.com/xcodeswift/xcproj/pull/244 by @briantkelley -- `PBXContainerItem` super class of `PBXFileElement` https://github.com/xcodeswift/xcproj/pull/244 by @briantkelley -- `PBXVariantGroup` and `XCVersionGroup` now inherit from `PBXGroup` https://github.com/xcodeswift/xcproj/pull/244 by @briantkelley - -### Fixed - -- `PBXObject.isEqual(to:)` overrides correctly call super https://github.com/xcodeswift/xcproj/pull/239 by @briantkelley -- `PBXAggregateTarget` does not write `buildRules` https://github.com/xcodeswift/xcproj/pull/241 by @briantkelley -- Writes showEnvVarsInLog only when false https://github.com/xcodeswift/xcproj/pull/240 by @briantkelley -- Writes `PBXProject.projectReferences` to the plist https://github.com/xcodeswift/xcproj/pull/242 by @briantkelley -- Comment generation for `PBXProject`, `PBXTarget`, and `PBXVariantGroup` https://github.com/xcodeswift/xcproj/pull/243 by @briantkelley -- `fullPath` now returns the path for a file inside a group without a folder https://github.com/xcodeswift/xcproj/pull/246 by @ileitch -- Quotes strings containing a triple underscore or double forward slash in .pbxproj file https://github.com/xcodeswift/xcproj/pull/245 by @briantkelley - -## 4.1.0 - -### Added - -- Added `tvOS` and `watchOS` Carthage support https://github.com/xcodeswift/xcproj/pull/232 by @yonaskolb -- Added support for scheme environment variables https://github.com/xcodeswift/xcproj/pull/227 by @turekj - -### Fixed - -- Fixed PBXObject sublasses from checking Equatable properly https://github.com/xcodeswift/xcproj/pull/224 by @yonaskolb -- Fix Carthage support https://github.com/xcodeswift/xcproj/pull/226 by @ileitch -- Fix adding file reference to bundle and package files https://github.com/xcodeswift/xcproj/pull/234 by @fuzza -- Fix adding PBXGroup without folder reference https://github.com/xcodeswift/xcproj/pull/235 by @fuzza -- Fixed some more diffs from Xcode https://github.com/xcodeswift/xcproj/pull/233 by @yonaskolb - -### Changed - -- Carthage minimum Deployment Target https://github.com/xcodeswift/xcproj/pull/229 by @olbrichj - -### 4.0.0 - -### Added - -- Added support for scheme pre-actions and post-actions https://github.com/xcodeswift/xcproj/pull/217 by @kastiglione - -### Changed - -- **Breaking:** Changed the return type of some helper functions that create or fetch PBXObjects to be `ObjectReference`, which includes the reference as well as the object https://github.com/xcodeswift/xcproj/pull/218 by @yonaskolb -- **Breaking:** Changed some `Int` properties into `Bool` or `UInt` https://github.com/xcodeswift/xcproj/pull/221 by @yonaskolb -- Changed the writing of some properties to minimise diffs when opening projects in Xcode https://github.com/xcodeswift/xcproj/pull/220 by @yonaskolb - -## 3.0.0 - -### Fixed - -- Fix Xcode 9.2 warning https://github.com/xcodeswift/xcproj/pull/209 by @keith -- macOS CLI targets now have a nil extension, instead of an empty string https://github.com/xcodeswift/xcproj/pull/208 by @keith -- Fix unnecessary quotations in CommentedString https://github.com/xcodeswift/xcproj/pull/211 by @allu22 -- Fixed xml files format not matching Xcode format, added some missing actions attributes. https://github.com/xcodeswift/xcproj/pull/216 by @ilyapuchka - -### Changed - -- **Breaking:** `XCWorkspace.Data` renamed to `XCWorkspaceData` and removed `references`. -- Improved README examples. https://github.com/xcodeswift/xcproj/pull/212 by @ilyapuchka -- Added methods to get paths to workspace, project and breakpoints and shemes files, added public methods to write them separatery. https://github.com/xcodeswift/xcproj/pull/215 by @ilyapuchka -- Added helper methods for adding source file to the project. https://github.com/xcodeswift/xcproj/pull/213 by @ilyapuchka - -## 2.0.0 - -### Added - -- Deterministic reference generation https://github.com/xcodeswift/xcproj/pull/185 by @pepibumur - -### Removed - -- **Breaking Change** `Referenceable` protocol https://github.com/xcodeswift/xcproj/pull/185 by @pepibumur. -- **Breaking Change** Deprecated methods to access objects from the `PBXProj`. Developers should use the `PBXProj.objects` property instead. https://github.com/xcodeswift/xcproj/pull/185 by @pepibumur. - -### Fixed - -- **Breaking:** `PBXSourceTree` no longer has raw values and gained an associated value case to support custom locations https://github.com/xcodeswift/xcproj/pull/198 by @briantkelley - -### Changed - -- **Breaking:** The `buildableProductRunnable` property on`XCScheme.LaunchAction` and `XCScheme.ProfileAction` is now optional. Similarly, `macroExpansion` on `XCScheme.TestAction` is also optional. https://github.com/xcodeswift/xcproj/pull/194 by @briantkelley -- The `XCScheme` initialization from an XML file has been relaxed, better matching Xcode's behavior. Default values will be used if the XML file is missing the relevant element or attribute. https://github.com/xcodeswift/xcproj/pull/194 by @briantkelley - -### Migrate from 1.x.x to 2.x.x - -- If you were using objects getters in `PBXProj` you should use the getters in `PBXProj.objects` instead. -- Objects don't include a `reference` property anymore. Objects associated references are the keys in the dictionary that contains them. -- When objects are added to the `PBXProj.objects` collection a reference needs to be passed. The reference can be calculated using the function `PBXProj.objects.generateReference` that generates a unique and deterministic reference based on the given object and identifier. -- If you were using `buildableProductRunnable` and `macroExpansion` properties from `XCScheme` actions they are now optionals. - -## 1.8.0 - -### Fixed - -- Optimised performance of object lookups https://github.com/xcodeswift/xcproj/pull/191 by @kastiglione - -### Added - -- Add breakpoint `condition` parameter by [@alexruperez](https://github.com/alexruperez). -- Support Xcode Extension product type https://github.com/xcodeswift/xcproj/pull/190 by @briantkelley -- Support for the legacy Build Carbon Resources build phase https://github.com/xcodeswift/xcproj/pull/196 by @briantkelley -- Support for custom build rules by https://github.com/xcodeswift/xcproj/pull/197 @briantkelley - -### Fixed - -- Optimised escaping of CommentedString https://github.com/xcodeswift/xcproj/pull/195 by @kastiglione -- Optimised performance of object lookups https://github.com/xcodeswift/xcproj/pull/191 by @kastiglione -- fixed PBXLegacyTarget write order https://github.com/xcodeswift/xcproj/pull/199 by @kastiglione -- fixed comment generation of PBXBuildFiles without a name https://github.com/xcodeswift/xcproj/pull/203 by @briantkelley -- fixed PBXReferenceTarget encoding in pbxproj file https://github.com/xcodeswift/xcproj/pull/202 by @briantkelley - -## 1.7.0 - -### Added - -- Support more indentation options on PBXGroups https://github.com/xcodeswift/xcproj/pull/168 by @bkase. -- Support `PBXLegacyTarget` https://github.com/xcodeswift/xcproj/pull/171 by @bkase. -- Breakpoint support through `XCBreakpointList`. https://github.com/xcodeswift/xcproj/pull/172 by [@alexruperez](https://github.com/alexruperez) -- Add convenience method to find targets with a given name https://github.com/xcodeswift/xcproj/pull/184 by @pepibumur. -- Danger plugin that fails earlier if files have been added/deleted and the Carthage project hasn't been regenerated afterwards https://github.com/xcodeswift/xcproj/pull/187 by @pepibumur. - -## 1.6.1 - -### Fixed - -- Fix encoded line breaks in PBXFileReference https://github.com/xcodeswift/xcproj/pull/177 by @yonaskolb - -## 1.6.0 - -### Added - -- PBXLegacyTarget support https://github.com/xcodeswift/xcproj/pull/171 by @bkase -- Integration tests https://github.com/xcodeswift/xcproj/pull/168 by @pepibumur -- More examples to the README https://github.com/xcodeswift/xcproj/pull/116 by @pepibumur. -- Add adding / editing command line arguments for Launch, Test and Profile Actions in `XCScheme`. https://github.com/xcodeswift/xcproj/pull/167 by @rahul-malik -- Test the contract with XcodeGen https://github.com/xcodeswift/xcproj/pull/170 by @pepibumur -- Add `PBXProj.Objects.getFileElement` https://github.com/xcodeswift/xcproj/pull/175 by @yonaskolb - -### Fixed - -- `PBXGroup` not generating the comment properly for its children https://github.com/xcodeswift/xcproj/pull/169 by @pepibumur. -- Make `PBXFileElement` a superclass for `PBXFileReference`, `PBXGroup`, and `PBXVariantGroup` https://github.com/xcodeswift/xcproj/pull/173 by @gubikmic -- Added `path` to `PBXVariantGroup` init https://github.com/xcodeswift/xcproj/pull/174 by @yonaskolb - -## 1.5.0 - -### Added - -- Add `codeCoverageEnabled` parameter to `TestAction` https://github.com/xcodeswift/xcproj/pull/166 by @kastiglione -- Make `final` classes that are not extendible https://github.com/xcodeswift/xcproj/pull/164 by @pepibumur. - -### Fixed - -- Fix `PBXProject` `productRefGroup` comment https://github.com/xcodeswift/xcproj/pull/161 by @allu22 -- Fix deprecation warnings for `PBXProj` objects usage https://github.com/xcodeswift/xcproj/pull/162 by @rahul-malik - -## 1.4.0 - Take me out - -### Added - -- Danger integration https://github.com/xcodeswift/xcproj/pull/158 by @pepibumur - -### Changed - -- Improve efficiency of looking up `PBXObject`'s from `PBXProj` https://github.com/xcodeswift/xcproj/pull/136 by @rahul-malik - -### Deprecated - -- `PBXObject` objects accessors https://github.com/xcodeswift/xcproj/pull/136/files#diff-f4369d9af58a6914f0e5cdf81ed18530R6 by @rahul-malik. - -### Fixed - -- Fix `PBXBuildFile` wrongly defaulting the settings attribute when it was nil https://github.com/xcodeswift/xcproj/pull/149 by @allu22 -- Fix `PBXTarget` generating the wrong comment for the `productReference` property https://github.com/xcodeswift/xcproj/pull/151 by @allu22. -- Add missing `usesTabs` property to `PBXGroup` https://github.com/xcodeswift/xcproj/pull/147 by @allu22. -- Fix generated comment for `PBXHeadersBuildPhase` by @allu22. -- Fix wrong `BuidlSettings.swift` file name https://github.com/xcodeswift/xcproj/pull/146 by @allu22. -- Fix `projectReferences` type https://github.com/xcodeswift/xcproj/pull/135 by @solgar. - -### Added - -- Danger checks https://github.com/xcodeswift/xcproj/pull/160 by @pepibumur -- New product type `ocUnitTestBundle` https://github.com/xcodeswift/xcproj/pull/134 by @solgar. - -## 1.3.0 - Esbarzers - -### Added - -- Add `PBXSourceTree.developerDir` type https://github.com/xcodeswift/xcproj/commit/5504fcde00bc56cf6c240ecd7cc36c05296861f8 by @pepibumur. - -### Fixed - -- Fix `PBXShellScriptBuildPhase` bug decoding `showEnvVarsInLog` https://github.com/xcodeswift/xcproj/commit/521b4e62b70f5fc43a06d00c43916d4899138553 by @pepibumur. -- Fix `PBXFileReference` bug decoding `useTabs` https://github.com/xcodeswift/xcproj/commit/c533987496959a3e32c0ddfe45a0f2db8d5daae0 by @pepibumur. -- Fix `PBXFileReference` bug decoding `lineEnding` https://github.com/xcodeswift/xcproj/commit/8a2c94effbe94859a68d58e0c49d66156ba1eaea by @pepibumur. - -## 1.2.0 - Two shoes - -### Added - -- Carthage support https://github.com/xcodeswift/xcproj/pull/125 by @pepibumur. -- `buildPhases` property to `PBXProj` https://github.com/xcodeswift/xcproj/pull/132 by @pepibumur. - -### Fixed - -- Build phase `buildActionMask` wrong default value https://github.com/xcodeswift/xcproj/pull/131 by @pepibumur. - -## 1.1.0 - Muerdo - -### Added - -- It supports now SPM-generated projects https://github.com/xcodeswift/xcproj/pull/124 by @pepibumur. Thanks @josefdolezal for the report. -- Project and workspace initializer that takes the path as a string https://github.com/xcodeswift/xcproj/pull/123 by @pepibumur. - -### Fixed - -- Fix the decoding of the `PBXFileReference.fileEncoding` property https://github.com/xcodeswift/xcproj/pull/127 by @gubikmic. -- Fix some wrong comments and typos https://github.com/xcodeswift/xcproj/pull/126 by @gubikmic - -## 1.0.0 - Acho - -### Changed - -- **Breaking:** Review optionality of attributes to align it with Xcode one https://github.com/xcodeswift/xcproj/pull/107 by @pepibumur. -- Contributing, and code of conduct point to the organization ones by @pepibumur. -- New changelog format introduced by @pepibumur. - -### Fixed - -- Use the super init to decode reference in some objects https://github.com/xcodeswift/xcproj/pull/110 by @yonaskolb -- Schemes being shared with an extension https://github.com/xcodeswift/xcproj/pull/113 by @esttorhe. -- Contributors link in the README.md https://github.com/xcodeswift/xcproj/pull/117 by @tapanprakasht. - -### Security - -## 0.4.1 - -- Add back the `BuildSettings` typelias removed by mistake https://github.com/xcodeswift/xcproj/pull/109 by @pepibumur. -- Fix a bug decoding the `PBXProject.projectRoot` property that should be decoded as an optional https://github.com/xcodeswift/xcproj/issues/108 by @pepibumur. - -## 0.4.0 - -- Remove dependency with Unbox and use the language coding/decoding features https://github.com/xcodeswift/xcproj/pull/99 by @pepibumur and @artemnovichkov. -- Enable xcproj in [Open Collective](https://opencollective.com/xcproj) by @pepibumur. -- Support parsing XCVersionGroup objects https://github.com/xcodeswift/xcproj/pull/96 by @pepibumur. -- Add iOS support to the `.podspec` https://github.com/xcodeswift/xcproj/pull/92 by @pepibumur. -- Fix comment for buildConfigurationList https://github.com/xcodeswift/xcproj/pull/93 by @toshi0383. -- Update `PBXProj` classes property to be a dictionary https://github.com/xcodeswift/xcproj/pull/94 by @toshi0383. -- Fix comment in the `BuildPhase` object https://github.com/xcodeswift/xcproj/pull/95 by @toshi0383. - -## 0.3.0 - -- Turn `PBXVariantGroup` children property into an array https://github.com/xcodeswift/xcproj/pull/88 by @pepibumur -- Add `PBXReferenceProxy` object https://github.com/xcodeswift/xcproj/pull/85 by @pepibumur -- Migrate project to Swift 4 https://github.com/xcodeswift/xcproj/pull/84 by @artemnovichkov -- Fix build phase script error undoer Xcode 9 https://github.com/xcodeswift/xcproj/pull/81 by @kixswift - -## 0.2.0 - -- Add how to use section https://github.com/xcodeswift/xcproj/pull/77 by @pepibumur -- Add contributing guidelines https://github.com/xcodeswift/xcproj/pull/76 by @pepibumur - -## 0.1.2 - -- Update shell build script phase input and output files to be array instead of set https://github.com/xcodeswift/xcproj/issues/65 by @pepibumur -- Fix wrong comment in the shell script build phase https://github.com/xcodeswift/xcproj/issues/67 by @ppeibumur -- Fix wron gcomment in `PBXSourcesBuildPhase` files property https://github.com/xcodeswift/xcproj/issues/68 by @pepibumur -- Add `XCVersionGroup` project element used by Core Data models https://github.com/xcodeswift/xcproj/issues/69 by @pepibumur -- Update `XCConcigurationList` build configurations to be an array https://github.com/xcodeswift/xcproj/issues/70 by @pepibumur - -## 0.1.1 - -- Change `BuildSettings` to `[String: Any]` https://github.com/xcodeswift/xcproj/pull/52 by @yonaskolb -- Plist fixes https://github.com/xcodeswift/xcproj/pull/54 by @yonaskolb - -## 0.1.0 - -- Update struct to classes and clean up API https://github.com/xcodeswift/xcproj/pull/51 by @yonaskolb -- Fix and cleanup strings escaping https://github.com/xcodeswift/xcproj/pull/48 by @yonaskolb -- Add `runOnlyForDeploymentPostprocessing` to `PBXShellScriptBuildPhase` by @yonaskolb -- Remove force unwrap for `XCScheme` https://github.com/xcodeswift/xcproj/pull/39 by @Shakarang - -## 0.0.9 - -- CocoaPods support https://github.com/xcodeswift/xcproj/pull/35 by @pepibumur -- Make project models mutable https://github.com/xcodeswift/xcproj/pull/33 by @yonaskolb - -## 0.0.7 - -- Downgrade Swift Tools versions to 4.0 https://github.com/xcodeswift/xcproj/pull/27 by @yonaskolb -- Make Scheme intializers public https://github.com/xcodeswift/xcproj/pull/28 by @yonaskolb -- Change PBXGroup.children to be an array https://github.com/xcodeswift/xcproj/pull/26 by @yonaskolb -- Make XcodeProj writable https://github.com/xcodeswift/xcproj/pull/20 by @yonaskolb -- Write baseConfigurationReference https://github.com/xcodeswift/xcproj/pull/24 by @yonaskolb -- Convert booleans to YES or NO https://github.com/xcodeswift/xcproj/pull/23 by @yonaskolb -- Make more properties public https://github.com/xcodeswift/xcproj/pull/19 by @yonaskolb - -## 0.0.6 - -- Fix an issue with unescaped strings by @yonaskolb https://github.com/xcodeswift/xcproj/issues/16 -- Update Swift Tools Version to 4.0 https://github.com/xcodeswift/xcproj/commit/f0f5ffe58ce0d29bb986189abf6391c6552fd347 -- Remove CryptoSwift dependency https://github.com/xcodeswift/xcproj/commit/f0f5ffe58ce0d29bb986189abf6391c6552fd347 - -## 0.0.5 - -- Remove `UUID` typealias https://github.com/xcodeswift/xcproj/pull/15 -- Add `UUID` identifier generation from `PBXProj` https://github.com/xcodeswift/xcproj/pull/14 - -## 0.0.4 - -- Writing support for `PBXProj` - https://github.com/xcodeswift/xcproj/pull/8 -- Document RELEASE process https://github.com/xcodeswift/xcproj/pull/7. -- Add documentation https://github.com/xcodeswift/xcproj/pull/6 - -## 0.0.1 - -- First version of the Swift library. -- It supports **reading** and parsing the following models: - xcodeproj. - xcworkspace. - pbxproj. - > This version doesn't support writing yet + diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 00000000..fd69f534 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,111 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + +[remote.github] +owner = "tuist" +repo = "XcodeProj" +# token = "" + +[changelog] +# template for the changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} + +{% if version -%} + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else -%} + ## [Unreleased] +{% endif -%} + +### Details\ + +{% for group, commits in commits | group_by(attribute="group") %} + #### {{ group | upper_first }} + {%- for commit in commits %} + - {{ commit.message | upper_first | trim }}\ + {% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%} + {% if commit.github.pr_number %} in \ + [#{{ commit.github.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.github.pr_number }}) \ + {%- endif -%} + {% endfor %} +{% endfor %} + +{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} + ## New Contributors +{%- endif -%} + +{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} + * @{{ contributor.username }} made their first contribution + {%- if contributor.pr_number %} in \ + [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ + {%- endif %} +{%- endfor %}\n +""" +# template for the changelog footer +footer = """ +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} + +{% for release in releases -%} + {% if release.version -%} + {% if release.previous.version -%} + [{{ release.version | trim_start_matches(pat="v") }}]: \ + {{ self::remote_url() }}/compare/{{ release.previous.version }}..{{ release.version }} + {% endif -%} + {% else -%} + [unreleased]: {{ self::remote_url() }}/compare/{{ release.previous.version }}..HEAD + {% endif -%} +{% endfor %} + +Check out [GitHub releases](https://github.com/tuist/XcodeProj/releases) for older releases. + + +""" +# remove the leading and trailing whitespace from the templates +trim = true +# postprocessors +postprocessors = [] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # remove issue numbers from commits + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }, +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = false +# regex for matching git tags +tag_pattern = "[0-9].*" +# regex for skipping tags +skip_tags = "beta|alpha" +# regex for ignoring tags +ignore_tags = "rc" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "newest" + +[bump] +breaking_always_bump_major = true +features_always_bump_minor=true +initial_tag="8.22.0" From 3ed8d9f551100ead75e49c22e02de383e87914d7 Mon Sep 17 00:00:00 2001 From: Pedro Date: Sun, 11 Aug 2024 19:03:37 +0200 Subject: [PATCH 12/13] Force release From 2b14180320b6c709597760ffde7b4c5a4a639153 Mon Sep 17 00:00:00 2001 From: pepicrft Date: Sun, 11 Aug 2024 17:07:38 +0000 Subject: [PATCH 13/13] [Release] XcodeProj 8.23.0 --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71ffcc40..4ad59985 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [8.23.0] - 2024-08-11 ### Details #### Chore +- Continuously release releasable changes by @pepicrft in [#842](https://github.com/tuist/XcodeProj/pull/842) +- Update dependency tuist to v4.23.0 by @renovate[bot] in [#839](https://github.com/tuist/XcodeProj/pull/839) +- Disable the renovatebot dashboard by @pepicrft in [#840](https://github.com/tuist/XcodeProj/pull/840) - Set up SwiftLint and SwiftFormat, run them against the project, and run them as part of the CI workflows by @pepicrft in [#836](https://github.com/tuist/XcodeProj/pull/836) #### Docs @@ -16,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Feat - Introduce the new Xcode 16 models `PBXFileSystemSynchronizedRootGroup` and `PBXFileSystemSynchronizedBuildFileExceptionSet` by @pepicrft in [#827](https://github.com/tuist/XcodeProj/pull/827) -[unreleased]: https://github.com/tuist/XcodeProj/compare/8.22.0..HEAD +[8.23.0]: https://github.com/tuist/XcodeProj/compare/8.22.0..8.23.0 + + +Check out [GitHub releases](https://github.com/tuist/XcodeProj/releases) for older releases.