From e2f062b6be56f63d9cc65ea6c041da28460de7d5 Mon Sep 17 00:00:00 2001 From: Roman Podymov Date: Thu, 15 Jul 2021 03:41:48 +0200 Subject: [PATCH 01/55] erouska (#1107) --- Docs/Examples.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Docs/Examples.md b/Docs/Examples.md index 19dc40975..27159d966 100644 --- a/Docs/Examples.md +++ b/Docs/Examples.md @@ -10,3 +10,4 @@ These are a bunch of real world examples of XcodeGen project specs. Feel free to - [scelis/XcodeGen-TestStickers](https://github.com/scelis/XcodeGen-TestStickers/blob/master/project.yml) - [minvws/nl-covid19-notification-app-ios](https://github.com/minvws/nl-covid19-notification-app-ios/blob/master/project.yml) - [pvinis/react-native-xcodegen](https://github.com/pvinis/react-native-xcodegen/blob/master/templates) +- [covid19cz/erouska-ios](https://github.com/covid19cz/erouska-ios/blob/develop/project.yml) From d35d22f08bede3180bcdaa2b3270faf3bcbc0a4d Mon Sep 17 00:00:00 2001 From: Jakub Bednar Date: Thu, 15 Jul 2021 04:10:34 +0200 Subject: [PATCH 02/55] Added support for dependency destination specification. (Resolves #1038) (#1039) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added support for dependency destination specification. (Resolves #1038) * More generic way covering more different dependency types. (#1038) * Added unit-test for each possible dependency combination. First test current embeding then the new one with custom copy spec. (#1038) * Review fixes. (#1038) * Minimized unit-test boiler-plate (#1038) * Update CHANGELOG.md Co-authored-by: Jakub Bednář Co-authored-by: Yonas Kolb --- CHANGELOG.md | 3 + Docs/ProjectSpec.md | 13 + Sources/ProjectSpec/Dependency.swift | 12 +- Sources/XcodeGenKit/PBXProjGenerator.swift | 67 +- .../Project.xcodeproj/project.pbxproj | 15 +- Tests/Fixtures/TestProject/project.yml | 3 + Tests/ProjectSpecTests/ProjectSpecTests.swift | 3 +- .../ProjectGeneratorTests.swift | 1417 +++++++++++++++++ 8 files changed, 1522 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4096688d2..4bcbc98de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next Version +### Added +- Allow specifying a `copy` setting for each dependency. [#1038](https://github.com/yonaskolb/XcodeGen/pull/1039) @JakubBednar + ## 2.24.0 ### Added diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 91d80e3f6..c99f14628 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -432,6 +432,19 @@ A dependency can be one of a 6 types: - [ ] **weak**: **Bool** - Whether the `Weak` setting is applied when linking the framework. Defaults to false - [ ] **platformFilter**: **String** - This field is specific to Mac Catalyst. It corresponds to the "Platforms" dropdown in the Frameworks & Libraries section of Target settings in Xcode. Available options are: **iOS**, **macOS** and **all**. Defaults is **all** - [ ] **platforms**: **[[Platform](#platform)]** - List of platforms this dependency should apply to. Defaults to all applicable platforms. +- **copy** - Copy Files Phase for this dependency. This only applies when `embed` is true. Must be specified as an object with the following fields: + - [x] **destination**: **String** - Destination of the Copy Files phase. This can be one of the following values: + - `absolutePath` + - `productsDirectory` + - `wrapper` + - `executables` + - `resources` + - `javaResources` + - `frameworks` + - `sharedFrameworks` + - `sharedSupport` + - `plugins` + - [ ] **subpath**: **String** - The path inside of the destination to copy the files. **Implicit Framework options**: diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 795d0ed60..2037bd444 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -17,6 +17,7 @@ public struct Dependency: Equatable { public var weakLink: Bool = weakLinkDefault public var platformFilter: PlatformFilter = platformFilterDefault public var platforms: Set? + public var copyPhase: BuildPhaseSpec.CopyFilesSettings? public init( type: DependencyType, @@ -27,7 +28,8 @@ public struct Dependency: Equatable { implicit: Bool = implicitDefault, weakLink: Bool = weakLinkDefault, platformFilter: PlatformFilter = platformFilterDefault, - platforms: Set? = nil + platforms: Set? = nil, + copyPhase: BuildPhaseSpec.CopyFilesSettings? = nil ) { self.type = type self.reference = reference @@ -38,6 +40,7 @@ public struct Dependency: Equatable { self.weakLink = weakLink self.platformFilter = platformFilter self.platforms = platforms + self.copyPhase = copyPhase } public enum PlatformFilter: String, Equatable { @@ -135,6 +138,10 @@ extension Dependency: JSONObjectConvertible { if let platforms: [ProjectSpec.Platform] = jsonDictionary.json(atKeyPath: "platforms") { self.platforms = Set(platforms) } + + if let object: JSONDictionary = jsonDictionary.json(atKeyPath: "copy") { + copyPhase = try BuildPhaseSpec.CopyFilesSettings(jsonDictionary: object) + } } } @@ -144,7 +151,8 @@ extension Dependency: JSONEncodable { "embed": embed, "codeSign": codeSign, "link": link, - "platforms": platforms?.map(\.rawValue).sorted() + "platforms": platforms?.map(\.rawValue).sorted(), + "copy": copyPhase?.toJSONValue(), ] if removeHeaders != Dependency.removeHeadersDefault { diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 3b4d4b188..033b0fe31 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -662,6 +662,7 @@ public class PBXProjGenerator { var dependencies: [PBXTargetDependency] = [] var targetFrameworkBuildFiles: [PBXBuildFile] = [] var frameworkBuildPaths = Set() + var customCopyDependenciesReferences: [PBXBuildFile] = [] var copyFilesBuildPhasesFiles: [BuildPhaseSpec.CopyFilesSettings: [PBXBuildFile]] = [:] var copyFrameworksReferences: [PBXBuildFile] = [] var copyResourcesReferences: [PBXBuildFile] = [] @@ -689,7 +690,11 @@ public class PBXProjGenerator { if dependency.removeHeaders { embedAttributes.append("RemoveHeadersOnCopy") } - return ["ATTRIBUTES": embedAttributes] + var retval: [String:Any] = ["ATTRIBUTES": embedAttributes] + if let copyPhase = dependency.copyPhase { + retval["COPY_PHASE"] = copyPhase + } + return retval } func getDependencyFrameworkSettings(dependency: Dependency) -> [String: Any]? { @@ -727,7 +732,10 @@ public class PBXProjGenerator { pbxBuildFile.platformFilter = platform let embedFile = addObject(pbxBuildFile) - if dependencyTarget.type.isExtension { + if dependency.copyPhase != nil { + // custom copy takes precedence + customCopyDependenciesReferences.append(embedFile) + } else if dependencyTarget.type.isExtension { // embed app extension extensions.append(embedFile) } else if dependencyTarget.type.isSystemExtension { @@ -807,7 +815,12 @@ public class PBXProjGenerator { let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true)) pbxBuildFile.platformFilter = platform let embedFile = addObject(pbxBuildFile) - copyFrameworksReferences.append(embedFile) + + if dependency.copyPhase != nil { + customCopyDependenciesReferences.append(embedFile) + } else { + copyFrameworksReferences.append(embedFile) + } } case .sdk(let root): @@ -858,7 +871,12 @@ public class PBXProjGenerator { let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true)) pbxBuildFile.platformFilter = platform let embedFile = addObject(pbxBuildFile) - copyFrameworksReferences.append(embedFile) + + if dependency.copyPhase != nil { + customCopyDependenciesReferences.append(embedFile) + } else { + copyFrameworksReferences.append(embedFile) + } } case .carthage(let findFrameworks, let linkType): @@ -923,7 +941,12 @@ public class PBXProjGenerator { settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true)) pbxBuildFile.platformFilter = platform let embedFile = addObject(pbxBuildFile) - copyFrameworksReferences.append(embedFile) + + if dependency.copyPhase != nil { + customCopyDependenciesReferences.append(embedFile) + } else { + copyFrameworksReferences.append(embedFile) + } } case .bundle: // Static and dynamic libraries can't copy resources @@ -969,7 +992,11 @@ public class PBXProjGenerator { let embedFile = addObject( PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true)) ) - copyFrameworksReferences.append(embedFile) + if dependency.copyPhase != nil { + customCopyDependenciesReferences.append(embedFile) + } else { + copyFrameworksReferences.append(embedFile) + } } else { carthageFrameworksToEmbed.append(dependency.reference) } @@ -1016,6 +1043,19 @@ public class PBXProjGenerator { ) } + func splitCopyDepsByDestination(_ references: [PBXBuildFile]) -> [BuildPhaseSpec.CopyFilesSettings : [PBXBuildFile]] { + + var retval = [BuildPhaseSpec.CopyFilesSettings : [PBXBuildFile]]() + for reference in references { + + guard let key = reference.settings?["COPY_PHASE"] as? BuildPhaseSpec.CopyFilesSettings else { continue } + var filesWithSameDestination = retval[key] ?? [PBXBuildFile]() + filesWithSameDestination.append(reference) + retval[key] = filesWithSameDestination + } + return retval + } + copyFilesBuildPhasesFiles.merge(getBuildFilesForCopyFilesPhases()) { $0 + $1 } buildPhases += try target.preBuildScripts.map { try generateBuildScript(targetName: target.name, buildScript: $0) } @@ -1154,6 +1194,21 @@ public class PBXProjGenerator { buildPhases.append(copyFilesPhase) } + if !customCopyDependenciesReferences.isEmpty { + + let splitted = splitCopyDepsByDestination(customCopyDependenciesReferences) + for (phase, references) in splitted { + + guard let destination = phase.destination.destination else { continue } + + let copyFilesPhase = addObject( + getPBXCopyFilesBuildPhase(dstSubfolderSpec: destination, dstPath:phase.subpath, name: "Embed Dependencies", files: references) + ) + + buildPhases.append(copyFilesPhase) + } + } + if !copyWatchReferences.isEmpty { let copyFilesPhase = addObject( diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 0e634a03d..edfa695ab 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -111,6 +111,7 @@ 7F658343A505B824321E086B /* Headers in Headers */ = {isa = PBXBuildFile; fileRef = 2E1E747C7BC434ADB80CC269 /* Headers */; settings = {ATTRIBUTES = (Public, ); }; }; 803B7CE086CFBA409F9D1ED7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 108BB29172D27BE3BD1E7F35 /* Assets.xcassets */; }; 818D448D4DDD6649B5B26098 /* example.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 28360ECA4D727FAA58557A81 /* example.mp4 */; settings = {ASSET_TAGS = (tag1, tag2, ); }; }; + 81DFAB3A7633CE97929B9B2A /* Framework.framework in Embed Dependencies */ = {isa = PBXBuildFile; fileRef = 41FC82ED1C4C3B7B3D7B2FB7 /* Framework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8267B75289E9D6C7B38FC426 /* DriverKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0A428E67153BB40184F37BE /* DriverKit.framework */; }; 87927928A8A3460166ACB819 /* SwiftFileInDotPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F430AABE04B7499B458D9DB /* SwiftFileInDotPath.swift */; settings = {COMPILER_FLAGS = "-Werror"; }; }; 8C941A6EF08069CB3CB88FC1 /* Result.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -142,7 +143,6 @@ BAA1C1E3828F5D43546AF997 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB1B49A91B892152D68ED76 /* libc++.tbd */; }; BB06A57E259D0D2A001EA21F /* Result.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BD1419893577E6CEDF8CBA83 /* Result.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - BD95416F2005199F6B3572CF /* Framework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 41FC82ED1C4C3B7B3D7B2FB7 /* Framework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BFCCC56337A5D9D513C1C791 /* module.modulemap in CopyFiles */ = {isa = PBXBuildFile; fileRef = F2950763C4C568CC85021D18 /* module.modulemap */; }; C093BF20B99FE892D0F06B2D /* libEndpointSecurity.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BC75409252FF15F540FBB7B /* libEndpointSecurity.tbd */; }; C3672B561F456794151C047C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4C3FE6B986506724DAB5D0F /* ViewController.swift */; }; @@ -578,6 +578,17 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; + CF6B94E7B2D2312582A526F5 /* Embed Dependencies */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = test; + dstSubfolderSpec = 13; + files = ( + 81DFAB3A7633CE97929B9B2A /* Framework.framework in Embed Dependencies */, + ); + name = "Embed Dependencies"; + runOnlyForDeploymentPostprocessing = 0; + }; DE875E9A37F7CB9C347AEFA0 /* Embed System Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -607,7 +618,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - BD95416F2005199F6B3572CF /* Framework.framework in Embed Frameworks */, A7D1A9942302569A9515696A /* Result.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -1529,6 +1539,7 @@ A6E1C88C073F8CC6B5B072B6 /* Frameworks */, DE875E9A37F7CB9C347AEFA0 /* Embed System Extensions */, F8CDEFED6ED131A09041F995 /* Embed Frameworks */, + CF6B94E7B2D2312582A526F5 /* Embed Dependencies */, ); buildRules = ( ); diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 10bbabffa..686471eb2 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -57,6 +57,9 @@ targets: optional: true dependencies: - target: Framework_macOS + copy: + destination: plugins + subpath: "test" - target: XPC Service - target: NetworkSystemExtension - target: EndpointSecuritySystemExtension diff --git a/Tests/ProjectSpecTests/ProjectSpecTests.swift b/Tests/ProjectSpecTests/ProjectSpecTests.swift index 07bbe8441..56b93c41d 100644 --- a/Tests/ProjectSpecTests/ProjectSpecTests.swift +++ b/Tests/ProjectSpecTests/ProjectSpecTests.swift @@ -398,7 +398,8 @@ class ProjectSpecTests: XCTestCase { codeSign: true, link: true, implicit: true, - weakLink: true)], + weakLink: true, + copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "example", phaseOrder: .postCompile))], info: Plist(path: "info.plist", attributes: ["foo": "bar"]), entitlements: Plist(path: "entitlements.plist", attributes: ["foo": "bar"]), transitivelyLinkDependencies: true, diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 9309c59aa..8b3d71ec9 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -1581,6 +1581,1423 @@ class ProjectGeneratorTests: XCTestCase { } } } + + func testGenerateXcodeProjectWithCustomDependencyDestinations() throws { + + describe("generateXcodeProject") { + + func generateProjectForApp(withDependencies: [Dependency], targets: [Target], packages: [String: SwiftPackage] = [:]) throws -> PBXProj { + + let app = Target( + name: "App", + type: .application, + platform: .macOS, + dependencies: withDependencies + ) + + let project = Project( + name: "test", + targets: targets + [app], + packages: packages + ) + + return try project.generatePbxProj() + } + + func expectCopyPhase(in project:PBXProj, withFilePaths: [String]? = nil, withProductPaths: [String]? = nil, toSubFolder subfolder: PBXCopyFilesBuildPhase.SubFolder, dstPath: String? = nil) throws { + + let phases = project.copyFilesBuildPhases + try expect(phases.count) == 1 + let phase = phases.first! + try expect(phase.dstSubfolderSpec) == subfolder + try expect(phase.dstPath) == dstPath + if let paths = withFilePaths { + try expect(phase.files?.count) == paths.count + let filePaths = phase.files!.map { $0.file!.path } + try expect(filePaths) == paths + } + if let paths = withProductPaths { + try expect(phase.files?.count) == paths.count + let filePaths = phase.files!.map { $0.product!.productName } + try expect(filePaths) == paths + } + } + + $0.context("with target dependencies") { + $0.context("application") { + + let appA = Target( + name: "appA", + type: .application, + platform: .macOS + ) + let appB = Target( + name: "appB", + type: .application, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true), + Dependency(type: .target, reference: appB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [ appA, appB ]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: appB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["appA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("framework") { + + let frameworkA = Target( + name: "frameworkA", + type: .framework, + platform: .macOS + ) + let frameworkB = Target( + name: "frameworkB", + type: .framework, + platform: .macOS + ) + + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true), + Dependency(type: .target, reference: frameworkB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: frameworkB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("staticFramework") { + + let frameworkA = Target( + name: "frameworkA", + type: .staticFramework, + platform: .macOS + ) + let frameworkB = Target( + name: "frameworkB", + type: .staticFramework, + platform: .macOS + ) + + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true), + Dependency(type: .target, reference: frameworkB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: frameworkB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("xcFramework") { + + let frameworkA = Target( + name: "frameworkA", + type: .xcFramework, + platform: .macOS + ) + let frameworkB = Target( + name: "frameworkB", + type: .xcFramework, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true), + Dependency(type: .target, reference: frameworkB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: frameworkA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: frameworkB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.xcframework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("Dynamic Library") { + + let libraryA = Target( + name: "libraryA", + type: .dynamicLibrary, + platform: .macOS + ) + let libraryB = Target( + name: "libraryB", + type: .dynamicLibrary, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true), + Dependency(type: .target, reference: libraryB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: libraryB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["libraryA.dylib"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("Static Library") { + + let libraryA = Target( + name: "libraryA", + type: .staticLibrary, + platform: .macOS + ) + let libraryB = Target( + name: "libraryB", + type: .staticLibrary, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true), + Dependency(type: .target, reference: libraryB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them to custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: libraryB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["liblibraryA.a"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("bundle") { + + let bundleA = Target( + name: "bundleA", + type: .bundle, + platform: .macOS + ) + let bundleB = Target( + name: "bundleB", + type: .bundle, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true), + Dependency(type: .target, reference: bundleB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: bundleB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.bundle"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("unitTestBundle") { + + let bundleA = Target( + name: "bundleA", + type: .unitTestBundle, + platform: .macOS + ) + let bundleB = Target( + name: "bundleB", + type: .unitTestBundle, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true), + Dependency(type: .target, reference: bundleB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: bundleB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.xctest"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("uitTestBundle") { + + let bundleA = Target( + name: "bundleA", + type: .uiTestBundle, + platform: .macOS + ) + let bundleB = Target( + name: "bundleB", + type: .uiTestBundle, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true), + Dependency(type: .target, reference: bundleB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: bundleB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.xctest"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("appExtension") { + + let extA = Target( + name: "extA", + type: .appExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .appExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .executables, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .executables, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .executables, dstPath: "test") + } + } + + $0.context("commandLineTool") { + + let toolA = Target( + name: "toolA", + type: .commandLineTool, + platform: .macOS + ) + let toolB = Target( + name: "toolB", + type: .commandLineTool, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: toolA.name, embed: true), + Dependency(type: .target, reference: toolB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [toolA, toolB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: toolA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: toolB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [toolA, toolB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["toolA"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("watchApp") { + + let appA = Target( + name: "appA", + type: .watchApp, + platform: .macOS + ) + let appB = Target( + name: "appB", + type: .watchApp, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true), + Dependency(type: .target, reference: appB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: appB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["appA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("watch2App") { + + let appA = Target( + name: "appA", + type: .watch2App, + platform: .macOS + ) + let appB = Target( + name: "appB", + type: .watch2App, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true), + Dependency(type: .target, reference: appB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: appB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["appA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("watch2AppContainer") { + + let appA = Target( + name: "appA", + type: .watch2AppContainer, + platform: .macOS + ) + let appB = Target( + name: "appB", + type: .watch2AppContainer, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true), + Dependency(type: .target, reference: appB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: appB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["appA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("watchExtension") { + + let extA = Target( + name: "extA", + type: .watchExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .watchExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("watch2Extension") { + + let extA = Target( + name: "extA", + type: .watch2Extension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .watch2Extension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("tvExtension") { + + let extA = Target( + name: "extA", + type: .tvExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .tvExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("messagesApplication") { + + let appA = Target( + name: "appA", + type: .messagesApplication, + platform: .macOS + ) + let appB = Target( + name: "appB", + type: .messagesApplication, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true), + Dependency(type: .target, reference: appB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: appA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: appB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [appA, appB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["appA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("messagesExtension") { + + let extA = Target( + name: "extA", + type: .messagesExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .messagesExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("stickerPack") { + + let extA = Target( + name: "extA", + type: .stickerPack, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .stickerPack, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("xpcService") { + + let xpcA = Target( + name: "xpcA", + type: .xpcService, + platform: .macOS + ) + let xpcB = Target( + name: "xpcB", + type: .xpcService, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: xpcA.name, embed: true), + Dependency(type: .target, reference: xpcB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [xpcA, xpcB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["xpcA.xpc"], toSubFolder: .productsDirectory, dstPath: "$(CONTENTS_FOLDER_PATH)/XPCServices") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: xpcA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: xpcB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [xpcA, xpcB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["xpcA.xpc"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("ocUnitTestBundle") { + + let bundleA = Target( + name: "bundleA", + type: .ocUnitTestBundle, + platform: .macOS + ) + let bundleB = Target( + name: "bundleB", + type: .ocUnitTestBundle, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true), + Dependency(type: .target, reference: bundleB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: bundleA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: bundleB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [bundleA, bundleB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.octest"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("xcodeExtension") { + + let extA = Target( + name: "extA", + type: .xcodeExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .xcodeExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("instrumentsPackage") { + + let pkgA = Target( + name: "pkgA", + type: .instrumentsPackage, + platform: .macOS + ) + let pkgB = Target( + name: "pkgB", + type: .instrumentsPackage, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: pkgA.name, embed: true), + Dependency(type: .target, reference: pkgB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [pkgA, pkgB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: pkgA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: pkgB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [pkgA, pkgB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["pkgA.instrpkg"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("intentsServiceExtension") { + + let extA = Target( + name: "extA", + type: .intentsServiceExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .intentsServiceExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .plugins, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .frameworks, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .frameworks, dstPath: "test") + } + } + + $0.context("appClip") { + + let clipA = Target( + name: "clipA", + type: .onDemandInstallCapableApplication, + platform: .macOS + ) + let clipB = Target( + name: "clipB", + type: .onDemandInstallCapableApplication, + platform: .macOS + ) + + $0.it("does embed them into products directory without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: clipA.name, embed: true), + Dependency(type: .target, reference: clipB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [clipA, clipB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["clipA.app"], toSubFolder: .productsDirectory, dstPath: "$(CONTENTS_FOLDER_PATH)/AppClips") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: clipA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: clipB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [clipA, clipB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["clipA.app"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("Metal Library") { + + let libraryA = Target( + name: "libraryA", + type: .metalLibrary, + platform: .macOS + ) + let libraryB = Target( + name: "libraryB", + type: .metalLibrary, + platform: .macOS + ) + + $0.it("does not embed them without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true), + Dependency(type: .target, reference: libraryB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expect(pbxProject.copyFilesBuildPhases.count) == 0 + } + + $0.it("embeds them to custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: libraryA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: libraryB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [libraryA, libraryB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["libraryA.metallib"], toSubFolder: .plugins, dstPath: "test") + } + } + } + + $0.context("with framework dependencies") { + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .framework, reference: "frameworkA.framework", embed: true), + Dependency(type: .framework, reference: "frameworkB.framework", embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .framework, reference: "frameworkA.framework", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .framework, reference: "frameworkB.framework", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .plugins, dstPath: "test") + } + + $0.it("generates single copy phase for multiple frameworks with same copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .framework, reference: "frameworkA.framework", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .framework, reference: "frameworkB.framework", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework", "frameworkB.framework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("with sdk dependencies") { + + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .sdk(root: nil), reference: "sdkA.framework", embed: true), + Dependency(type: .sdk(root: nil), reference: "sdkB.framework", embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["System/Library/Frameworks/sdkA.framework"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .sdk(root: nil), reference: "sdkA.framework", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .sdk(root: nil), reference: "sdkB.framework", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["System/Library/Frameworks/sdkA.framework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("with package dependencies") { + + let packages: [String: SwiftPackage] = [ + "RxSwift": .remote(url: "https://github.com/ReactiveX/RxSwift", versionRequirement: .upToNextMajorVersion("5.1.1")), + ] + + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .package(product: "RxSwift"), reference: "RxSwift", embed: true), + Dependency(type: .package(product: "RxCocoa"), reference: "RxSwift", embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [], packages: packages) + + // then + try expectCopyPhase(in: pbxProject, withProductPaths: ["RxSwift"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .package(product: "RxSwift"), reference: "RxSwift", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .package(product: "RxCocoa"), reference: "RxSwift", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [], packages: packages) + + // then + try expectCopyPhase(in: pbxProject, withProductPaths: ["RxSwift"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("with carthage dependencies") { + + $0.it("embeds them into frameworks without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "frameworkA.framework", embed: true), + Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "frameworkB.framework", embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .frameworks, dstPath: "") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "frameworkA.framework", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .carthage(findFrameworks: false, linkType: .static), reference: "frameworkB.framework", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["frameworkA.framework"], toSubFolder: .plugins, dstPath: "test") + } + } + + $0.context("with bundle dependencies") { + $0.it("embeds them into resources without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .bundle, reference: "bundleA.bundle", embed: true), + Dependency(type: .bundle, reference: "bundleB.bundle", embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + /// XcodeGen ignores embed: false for bundles + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.bundle", "bundleB.bundle"], toSubFolder: .resources) + } + + $0.it("ignores custom copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .bundle, reference: "bundleA.bundle", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .bundle, reference: "bundleB.bundle", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: []) + + // then + /// XcodeGen ignores embed: false for bundles + try expectCopyPhase(in: pbxProject, withFilePaths: ["bundleA.bundle", "bundleB.bundle"], toSubFolder: .resources) + } + } + } + } } private extension PBXTarget { From a4d7a61a6805f62b6da9f7ffb5cdf13a18d16a40 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 15 Jul 2021 18:06:33 +0900 Subject: [PATCH 03/55] Fix broken codesign option for bundle dependency (#1104) * Fix missing codesign option for bundle dependency * Add codeSign: false test case for bundle dependency * Update CHANGELOG.md --- CHANGELOG.md | 4 + Sources/XcodeGenKit/PBXProjGenerator.swift | 5 +- .../AnotherProject.xcodeproj/project.pbxproj | 102 ++++++++++++++++ .../TestProject/AnotherProject/project.yml | 3 + .../Project.xcodeproj/project.pbxproj | 114 +++++++++++++++++- Tests/Fixtures/TestProject/project.yml | 1 + 6 files changed, 227 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bcbc98de..eb97619e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ ### Added - Allow specifying a `copy` setting for each dependency. [#1038](https://github.com/yonaskolb/XcodeGen/pull/1039) @JakubBednar +### Fixed + +- Fix broken codesign option for bundle dependency [#1104](https://github.com/yonaskolb/XcodeGen/pull/1104) @kateinoigakukun + ## 2.24.0 ### Added diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 033b0fe31..4496f548c 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -958,7 +958,10 @@ public class PBXProjGenerator { sourceTree: .buildProductsDir ) - let pbxBuildFile = PBXBuildFile(file: fileReference, settings: nil) + let pbxBuildFile = PBXBuildFile( + file: fileReference, + settings: embed ? getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true) : nil + ) pbxBuildFile.platformFilter = platform let buildFile = addObject(pbxBuildFile) copyBundlesReferences.append(buildFile) diff --git a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj index c0b561029..add10f0bc 100644 --- a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 6023D61BF2C57E6AE09CE7A3 /* BundleX.bundle */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = BundleX.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 60D6679FB526839EAFEA2EEE /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; }; D6340FC7DEBC81E0127BAFD6 /* ExternalTarget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExternalTarget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F1EFFCA88BFC3A1DD2D89DA7 /* BundleY.bundle */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = BundleY.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -34,6 +35,7 @@ isa = PBXGroup; children = ( 6023D61BF2C57E6AE09CE7A3 /* BundleX.bundle */, + F1EFFCA88BFC3A1DD2D89DA7 /* BundleY.bundle */, D6340FC7DEBC81E0127BAFD6 /* ExternalTarget.framework */, ); name = Products; @@ -59,6 +61,20 @@ /* End PBXLegacyTarget section */ /* Begin PBXNativeTarget section */ + 201AC870383B8CD218AD0FAB /* BundleY */ = { + isa = PBXNativeTarget; + buildConfigurationList = EF9E2AA4073D3B2EC8195688 /* Build configuration list for PBXNativeTarget "BundleY" */; + buildPhases = ( + ); + buildRules = ( + ); + dependencies = ( + ); + name = BundleY; + productName = BundleY; + productReference = F1EFFCA88BFC3A1DD2D89DA7 /* BundleY.bundle */; + productType = "com.apple.product-type.bundle"; + }; 63A2D4898D974A06E85B07F8 /* BundleX */ = { isa = PBXNativeTarget; buildConfigurationList = 32C09717E388BCD9DB9E513C /* Build configuration list for PBXNativeTarget "BundleX" */; @@ -110,6 +126,7 @@ projectRoot = ""; targets = ( 63A2D4898D974A06E85B07F8 /* BundleX */, + 201AC870383B8CD218AD0FAB /* BundleY */, E76A5F5E363E470416D3B487 /* ExternalTarget */, A6D9FB94860C005F0B723B5F /* IncludedLegacy */, ); @@ -322,6 +339,18 @@ }; name = "Test Debug"; }; + 1CE986A8B593E707AB71BDBA /* Production Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Release"; + }; 270E1D32776D2D196D435FDA /* Staging Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -570,6 +599,18 @@ }; name = "Production Debug"; }; + 58F418B6745A09C6479FDD6E /* Staging Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Release"; + }; 5F14CE04E33ACD729A0EE6B6 /* Test Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -648,6 +689,18 @@ }; name = "Test Release"; }; + 816E80EA88CB645CE988138C /* Staging Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Debug"; + }; 9BD6CAD5463121A1C3FED138 /* Production Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -760,6 +813,42 @@ }; name = "Production Release"; }; + E7907C46C6282D78E009083B /* Test Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Debug"; + }; + FB66976FF75B2B0B255D5AA4 /* Test Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Release"; + }; + FD9323224BE5A91248B7BEF2 /* Production Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Debug"; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -815,6 +904,19 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = "Production Debug"; }; + EF9E2AA4073D3B2EC8195688 /* Build configuration list for PBXNativeTarget "BundleY" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FD9323224BE5A91248B7BEF2 /* Production Debug */, + 1CE986A8B593E707AB71BDBA /* Production Release */, + 816E80EA88CB645CE988138C /* Staging Debug */, + 58F418B6745A09C6479FDD6E /* Staging Release */, + E7907C46C6282D78E009083B /* Test Debug */, + FB66976FF75B2B0B255D5AA4 /* Test Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Production Debug"; + }; /* End XCConfigurationList section */ }; rootObject = 1B166EB49192B73A9DD8E108 /* Project object */; diff --git a/Tests/Fixtures/TestProject/AnotherProject/project.yml b/Tests/Fixtures/TestProject/AnotherProject/project.yml index 65e729ede..3c0cc4867 100644 --- a/Tests/Fixtures/TestProject/AnotherProject/project.yml +++ b/Tests/Fixtures/TestProject/AnotherProject/project.yml @@ -8,6 +8,9 @@ targets: BundleX: type: bundle platform: iOS + BundleY: + type: bundle + platform: iOS ExternalTarget: type: framework platform: iOS diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index edfa695ab..854a725f6 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -63,11 +63,12 @@ 339578307B9266AB3D7722D9 /* File2.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC56891DA7446EAC8C2F27EB /* File2.swift */; }; 3535891EC86283BB5064E7E1 /* Headers in Headers */ = {isa = PBXBuildFile; fileRef = 2E1E747C7BC434ADB80CC269 /* Headers */; settings = {ATTRIBUTES = (Public, ); }; }; 3788E1382B38DF4ACE3D2BB1 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3BBCA6F76E5F212E9C55FB78 /* BundleX.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 45C12576F5AA694DD0CE2132 /* BundleX.bundle */; }; + 3BBCA6F76E5F212E9C55FB78 /* BundleX.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 45C12576F5AA694DD0CE2132 /* BundleX.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 3C5134EE524310ACF7B7CD6E /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAF6C55B555E3E1352645B6 /* ExtensionDelegate.swift */; }; 42BC5788871D1D838B253952 /* App_watchOS Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0D09D243DBCF9D32E239F1E8 /* App_watchOS Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 447D59BE2E0993D7245EA247 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3797E591F302ECC0AA2FC607 /* Assets.xcassets */; }; 45E6702CD9C088FF1FC25F34 /* App_watchOS.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = A680BE9F68A255B0FB291AE6 /* App_watchOS.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 470D3493CDBFE56E2083A5FD /* BundleY.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = E3958AB20082EA12D4D5E60C /* BundleY.bundle */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 47D1F439B8E6D287B3F3E8D1 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 47FC57B04A3AD83359F433EA /* StaticLibrary_ObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5A2B916A11DCC2565241359F /* StaticLibrary_ObjC.h */; }; 49A4B8937BB5520B36EA33F0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 814D72C2B921F60B759C2D4B /* Main.storyboard */; }; @@ -608,6 +609,7 @@ dstSubfolderSpec = 7; files = ( 3BBCA6F76E5F212E9C55FB78 /* BundleX.bundle in Copy Bundle Resources */, + 470D3493CDBFE56E2083A5FD /* BundleY.bundle in Copy Bundle Resources */, ); name = "Copy Bundle Resources"; runOnlyForDeploymentPostprocessing = 0; @@ -765,6 +767,7 @@ B76E17CE3574081D5BF45B44 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; BA040F1F7D6CA08878323A55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; BB178D03E75929F3F5B10C56 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; + BB677D970923F663D846D7E0 /* BundleY.bundle */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = BundleY.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; BC56891DA7446EAC8C2F27EB /* File2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = File2.swift; path = Group2/File2.swift; sourceTree = ""; }; BDCA996D141DD8A16B18D68F /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "GoogleService-Info.plist"; sourceTree = ""; }; BECEA4A483ADEB8158F640B3 /* Tool */ = {isa = PBXFileReference; includeInIndex = 0; path = Tool; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -787,6 +790,7 @@ D8A016580A3B8F72B820BFBF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; DAA7880242A9DE61E68026CC /* Folder */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Folder; sourceTree = SOURCE_ROOT; }; DFE6A6FAAFF701FE729293DE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + E3958AB20082EA12D4D5E60C /* BundleY.bundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper.cfbundle; path = BundleY.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; E42335D1200CB7B8B91E962F /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = Base; path = Base.lproj/Localizable.stringsdict; sourceTree = ""; }; E43116070AFEF5D8C3A5A957 /* TestFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E55F45EACB0F382722D61C8D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -1168,6 +1172,7 @@ isa = PBXGroup; children = ( 45C12576F5AA694DD0CE2132 /* BundleX.bundle */, + E3958AB20082EA12D4D5E60C /* BundleY.bundle */, ); name = Bundles; sourceTree = ""; @@ -1264,6 +1269,7 @@ 0D09D243DBCF9D32E239F1E8 /* App_watchOS Extension.appex */, A680BE9F68A255B0FB291AE6 /* App_watchOS.app */, 84317819C92F78425870E483 /* BundleX.bundle */, + BB677D970923F663D846D7E0 /* BundleY.bundle */, 83B5EC7EF81F7E4B6F426D4E /* DriverKitDriver.dext */, E5E0A80CCE8F8DB662DCD2D0 /* EndpointSecuritySystemExtension.systemextension */, 7D700FA699849D2F95216883 /* EntitledApp.app */, @@ -1700,6 +1706,20 @@ productReference = A680BE9F68A255B0FB291AE6 /* App_watchOS.app */; productType = "com.apple.product-type.application.watchapp2"; }; + 271CAC331D24F4F7E12C819C /* BundleY */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA49CF5A1AC4FC1A7EE979E8 /* Build configuration list for PBXNativeTarget "BundleY" */; + buildPhases = ( + ); + buildRules = ( + ); + dependencies = ( + ); + name = BundleY; + productName = BundleY; + productReference = BB677D970923F663D846D7E0 /* BundleY.bundle */; + productType = "com.apple.product-type.bundle"; + }; 307AE3FA155FFD09B74AE351 /* App_watchOS Extension */ = { isa = PBXNativeTarget; buildConfigurationList = 3F3C272D2EA61F6B88B80D44 /* Build configuration list for PBXNativeTarget "App_watchOS Extension" */; @@ -2199,6 +2219,7 @@ 208179651927D1138D19B5AD /* App_watchOS */, 307AE3FA155FFD09B74AE351 /* App_watchOS Extension */, DA40AB367B606CCE2FDD398D /* BundleX */, + 271CAC331D24F4F7E12C819C /* BundleY */, 428715FBC1D86458DA70CBDE /* DriverKitDriver */, 9F551F66949B55E8328EB995 /* EndpointSecuritySystemExtension */, B61ED4688789B071275E2B7A /* EntitledApp */, @@ -4155,6 +4176,19 @@ }; name = "Production Debug"; }; + 414544E2FA4DE102442A71CD /* Production Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Release"; + }; 436FB4981A66822DAF6F22AC /* Production Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5005,6 +5039,19 @@ }; name = "Test Debug"; }; + 71529460FB00BCDF2064C57F /* Staging Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Debug"; + }; 72EDF2E14A4CE916F4E2B01B /* Staging Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5190,6 +5237,19 @@ }; name = "Test Debug"; }; + 7D73A7FB339A39293BD2DB9E /* Staging Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Release"; + }; 7E101F97604A0990174A46CD /* Staging Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5442,6 +5502,19 @@ }; name = "Production Release"; }; + 924BB9ED8B14A02ABF88CC23 /* Production Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Debug"; + }; 92602C025633FBA848F91812 /* Production Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -6090,6 +6163,19 @@ }; name = "Production Release"; }; + B227B91964080DEF6C426483 /* Test Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Debug"; + }; B24243F387A725EAFE802321 /* Production Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -6296,6 +6382,19 @@ }; name = "Production Release"; }; + BA21E149424C2D03E5E50EC1 /* Test Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.project.BundleY; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Release"; + }; BA5AD3137CD90C50E5E1BDA0 /* Production Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -8122,6 +8221,19 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = "Production Debug"; }; + DA49CF5A1AC4FC1A7EE979E8 /* Build configuration list for PBXNativeTarget "BundleY" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 924BB9ED8B14A02ABF88CC23 /* Production Debug */, + 414544E2FA4DE102442A71CD /* Production Release */, + 71529460FB00BCDF2064C57F /* Staging Debug */, + 7D73A7FB339A39293BD2DB9E /* Staging Release */, + B227B91964080DEF6C426483 /* Test Debug */, + BA21E149424C2D03E5E50EC1 /* Test Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Production Debug"; + }; ED1A174BA92C6E5172B519B7 /* Build configuration list for PBXNativeTarget "iMessageExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 686471eb2..4ba1de245 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -136,6 +136,7 @@ targets: - target: iMessageApp - sdk: Contacts.framework - bundle: BundleX.bundle + - { bundle: BundleY.bundle, codeSign: false } - target: AnotherProject/ExternalTarget - target: App_Clip onlyCopyFilesOnInstall: true From b04688845a77da1f06e92aa9a3601c42ab10ee18 Mon Sep 17 00:00:00 2001 From: Dan Loman Date: Mon, 2 Aug 2021 18:08:55 -0500 Subject: [PATCH 04/55] [bug fix] Ensure fileTypes are mapped to JSON value (#1112) * Ensure fileTypes are mapped to JSON value * Add CHANGELOG entry --- CHANGELOG.md | 1 + Sources/ProjectSpec/SpecOptions.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb97619e2..a67c68467 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed - Fix broken codesign option for bundle dependency [#1104](https://github.com/yonaskolb/XcodeGen/pull/1104) @kateinoigakukun +- Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad ## 2.24.0 diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index c1f0645d4..f70139ef7 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -187,7 +187,7 @@ extension SpecOptions: JSONEncodable { "localPackagesGroup": localPackagesGroup, "preGenCommand": preGenCommand, "postGenCommand": postGenCommand, - "fileTypes": fileTypes + "fileTypes": fileTypes.mapValues { $0.toJSONValue() } ] if settingPresets != SpecOptions.settingPresetsDefault { From f1e888f228292c568c12cd9899c983d19e111a19 Mon Sep 17 00:00:00 2001 From: Adam Wolf Date: Tue, 10 Aug 2021 15:37:51 -0700 Subject: [PATCH 05/55] Fix Usage.md link to options section (#1115) This actually was meant to link in to ProjectSpec.md#options --- Docs/Usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Usage.md b/Docs/Usage.md index a746650f4..c69ab3368 100644 --- a/Docs/Usage.md +++ b/Docs/Usage.md @@ -36,7 +36,7 @@ The values from [xcconfig files](#xcconfig-files) will then sit a level above th XcodeGen applies default settings to your project and targets similar to how Xcode creates them when you create a new project or target. Debug and Release settings will be applied to your project. Targets will also get specific settings depending on the platform and product type. ->You can change or disable how these setting presets are applied via the `options.settingPresets` which you can find more about in [Options](#options) +>You can change or disable how these setting presets are applied via the `options.settingPresets` which you can find more about in [Options](ProjectSpec.md#options) ### Settings The `project` and each `target` have a `settings` object that you can define. This can be a simple map of build settings or can provide build settings per `config` via `configs` or `base`. See [Settings](ProjectSpec.md#settings) for more details. From 12511afed82a3db1a9dbd814e835920c98d9914e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kry=C5=A1tof=20Mat=C4=9Bj?= Date: Tue, 14 Sep 2021 15:11:25 +0200 Subject: [PATCH 06/55] Fix platformFilter for package dependencies (#1123) --- CHANGELOG.md | 1 + Sources/XcodeGenKit/PBXProjGenerator.swift | 6 ++--- .../Project.xcodeproj/project.pbxproj | 27 +++++++++++++++++++ Tests/Fixtures/TestProject/project.yml | 7 +++++ .../PBXProjGeneratorTests.swift | 11 +++++--- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a67c68467..083704d34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Fix broken codesign option for bundle dependency [#1104](https://github.com/yonaskolb/XcodeGen/pull/1104) @kateinoigakukun - Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad +- Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz ## 2.24.0 diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 4496f548c..c02f3a34d 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -925,9 +925,9 @@ public class PBXProjGenerator { let link = dependency.link ?? (target.type != .staticLibrary) if link { - let buildFile = addObject( - PBXBuildFile(product: packageDependency, settings: getDependencyFrameworkSettings(dependency: dependency)) - ) + let file = PBXBuildFile(product: packageDependency, settings: getDependencyFrameworkSettings(dependency: dependency)) + file.platformFilter = platform + let buildFile = addObject(file) targetFrameworkBuildFiles.append(buildFile) } else { let targetDependency = addObject( diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 854a725f6..c0344eb31 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 09617AB755651FFEB2564CBC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F1A2F579A6F79C62DDA0571 /* AppDelegate.swift */; settings = {COMPILER_FLAGS = "-Werror"; }; }; 0AB541AE3163B063E7012877 /* StaticLibrary_ObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5A2B916A11DCC2565241359F /* StaticLibrary_ObjC.h */; }; 0BDA156BEBFCB9E65910F838 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0D0E2466833FC2636B92C43D /* Swinject in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = D7917D10F77DA9D69937D493 /* Swinject */; }; 0F99AECCB4691803C791CDCE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2FC2A8A829CE71B1CF415FF7 /* Main.storyboard */; }; 15129B8D9ED000BDA1FEEC27 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A2F16890ECF2EE3FED72AE /* AppDelegate.swift */; }; 1551370B0ACAC632E15C853B /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF47010E7368583405AA50CB /* SwiftyJSON.framework */; }; @@ -822,6 +823,7 @@ 2FAE950E8FF2E7C0F7FF1FE9 /* Framework.framework in Frameworks */, B142965C5AE9C6200BF65802 /* Result.framework in Frameworks */, B20617116B230DED1F7AF5E5 /* libStaticLibrary_ObjC.a in Frameworks */, + 0D0E2466833FC2636B92C43D /* Swinject in Frameworks */, 1551370B0ACAC632E15C853B /* SwiftyJSON.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1606,6 +1608,9 @@ 981D116D40DBA0407D0E0E94 /* PBXTargetDependency */, ); name = App_iOS; + packageProductDependencies = ( + D7917D10F77DA9D69937D493 /* Swinject */, + ); productName = App_iOS; productReference = B1C33BB070583BE3B0EC0E68 /* App_iOS.app */; productType = "com.apple.product-type.application"; @@ -2199,6 +2204,9 @@ en, ); mainGroup = 293D0FF827366B513839236A; + packageReferences = ( + 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */, + ); projectDirPath = ""; projectReferences = ( { @@ -8275,6 +8283,25 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Swinject/Swinject"; + requirement = { + kind = exactVersion; + version = 2.8.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + D7917D10F77DA9D69937D493 /* Swinject */ = { + isa = XCSwiftPackageProductDependency; + package = 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */; + productName = Swinject; + }; +/* End XCSwiftPackageProductDependency section */ + /* Begin XCVersionGroup section */ 306796628DD52FA55E833B65 /* Model.xcdatamodeld */ = { isa = XCVersionGroup; diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 4ba1de245..85662468a 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -27,6 +27,10 @@ projectReferences: path: ./AnotherProject/AnotherProject.xcodeproj configFiles: Test Debug: Configs/config.xcconfig +packages: + Swinject: + url: https://github.com/Swinject/Swinject + version: 2.8.0 targets: Legacy: type: "" @@ -139,6 +143,9 @@ targets: - { bundle: BundleY.bundle, codeSign: false } - target: AnotherProject/ExternalTarget - target: App_Clip + - package: Swinject + product: Swinject + platformFilter: iOS onlyCopyFilesOnInstall: true scheme: testTargets: diff --git a/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift b/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift index 359b6ce5f..f667ceb0e 100644 --- a/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift @@ -357,18 +357,23 @@ class PBXProjGeneratorTests: XCTestCase { let dependency1 = Dependency(type: .target, reference: "TestAll", platformFilter: .all) let dependency2 = Dependency(type: .target, reference: "TestiOS", platformFilter: .iOS) let dependency3 = Dependency(type: .target, reference: "TestmacOS", platformFilter: .macOS) - let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"], dependencies: [dependency1, dependency2, dependency3]) - let project = Project(basePath: directoryPath, name: "Test", targets: [target, target1, target2, target3]) + let dependency4 = Dependency(type: .package(product: "Swinject"), reference: "Swinject", platformFilter: .iOS) + let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"], dependencies: [dependency1, dependency2, dependency3, dependency4]) + let swinjectPackage = SwiftPackage.remote(url: "https://github.com/Swinject/Swinject", versionRequirement: .exact("2.8.0")) + let project = Project(basePath: directoryPath, name: "Test", targets: [target, target1, target2, target3], packages: ["Swinject": swinjectPackage]) let pbxProj = try project.generatePbxProj() let targets = pbxProj.projects.first?.targets - let testTargetDependencies = pbxProj.projects.first?.targets.first(where: { $0.name == "Test" })?.dependencies + let testTarget = pbxProj.projects.first?.targets.first(where: { $0.name == "Test" }) + let testTargetDependencies = testTarget?.dependencies try expect(targets?.count) == 4 try expect(testTargetDependencies?.count) == 3 try expect(testTargetDependencies?[0].platformFilter).beNil() try expect(testTargetDependencies?[1].platformFilter) == "ios" try expect(testTargetDependencies?[2].platformFilter) == "maccatalyst" + try expect(testTarget?.frameworksBuildPhase()?.files?.count) == 1 + try expect(testTarget?.frameworksBuildPhase()?.files?[0].platformFilter) == "ios" } } } From c3d936c0c7d42f906d35dde41a2ee887f680b59a Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Thu, 23 Sep 2021 18:52:00 +1000 Subject: [PATCH 07/55] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 083704d34..063ef0987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.25.0 + ### Added - Allow specifying a `copy` setting for each dependency. [#1038](https://github.com/yonaskolb/XcodeGen/pull/1039) @JakubBednar @@ -11,6 +13,8 @@ - Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad - Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz +[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) + ## 2.24.0 ### Added From 322262cff796d5314fcc62ebc3143dcd1ff7335e Mon Sep 17 00:00:00 2001 From: Yuya Oka Date: Thu, 23 Sep 2021 18:22:44 +0900 Subject: [PATCH 08/55] Update tuist/XcodeProj (#1125) * Update tuist/XcodeProj * Add changed entry --- CHANGELOG.md | 4 ++++ Package.resolved | 8 ++++---- Package.swift | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 063ef0987..14f36a1f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) +### Changed + +- Update XcodeProj to 8.2.0 [#1125](https://github.com/yonaskolb/XcodeGen/pull/1125) @nnsnodnb + ## 2.24.0 ### Added diff --git a/Package.resolved b/Package.resolved index 9c1119ed3..c6792473d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/tadija/AEXML", "state": { "branch": null, - "revision": "8623e73b193386909566a9ca20203e33a09af142", - "version": "4.5.0" + "revision": "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3", + "version": "4.6.1" } }, { @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/tuist/XcodeProj.git", "state": { "branch": null, - "revision": "0b18c3e7a10c241323397a80cb445051f4494971", - "version": "8.0.0" + "revision": "8e83191dba8bcbfc0be4d7c48bf1e02e7fedc88c", + "version": "8.2.0" } }, { diff --git a/Package.swift b/Package.swift index 899547eda..04715b575 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.9.2"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.0.0"), + .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.2.0"), .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.0"), .package(url: "https://github.com/mxcl/Version", from: "2.0.0"), .package(url: "https://github.com/SwiftDocOrg/GraphViz.git", .exact("0.2.0")), From fa6c5c9173d03157b25e014fce1b613465989bb6 Mon Sep 17 00:00:00 2001 From: Michael Thole <57376542+mthole@users.noreply.github.com> Date: Thu, 23 Sep 2021 16:11:10 -0700 Subject: [PATCH 09/55] Fix Xcode 13 build (alternate PR to kick CI) (#1130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Xcode 13 build * Extend Xcode 12 workaround to Xcode 13 * Update CHANGELOG * Moved CHANGELOG into 'Next Version' section Co-authored-by: Kryštof Matěj --- .github/workflows/ci.yml | 4 ++-- CHANGELOG.md | 4 ++++ Package.resolved | 18 +++++++++--------- Package.swift | 6 +++--- .../TestProject/carthage_dynamic.xcconfig | 2 +- .../TestProject/carthage_static.xcconfig | 2 +- Tests/Fixtures/TestProject/fixtures.xcconfig | 2 +- ...nfig => xcode12_and_13_workaround.xcconfig} | 1 + 8 files changed, 22 insertions(+), 17 deletions(-) rename Tests/Fixtures/TestProject/{xcode12_workaround.xcconfig => xcode12_and_13_workaround.xcconfig} (76%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c396e3489..39508bc5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,11 +4,11 @@ on: pull_request: {} jobs: run: - runs-on: macOS-latest + runs-on: macos-11 name: Xcode ${{ matrix.xcode }} strategy: matrix: - xcode: ["12"] + xcode: ["12.5.1", "13.0"] steps: - uses: actions/checkout@master - name: Set Xcode diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f36a1f6..908864e4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Fixed + +- Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole + ## 2.25.0 ### Added diff --git a/Package.resolved b/Package.resolved index c6792473d..4d75c7312 100644 --- a/Package.resolved +++ b/Package.resolved @@ -3,7 +3,7 @@ "pins": [ { "package": "AEXML", - "repositoryURL": "https://github.com/tadija/AEXML", + "repositoryURL": "https://github.com/tadija/AEXML.git", "state": { "branch": null, "revision": "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3", @@ -33,8 +33,8 @@ "repositoryURL": "https://github.com/kylef/PathKit.git", "state": { "branch": null, - "revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511", - "version": "1.0.0" + "revision": "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", + "version": "1.0.1" } }, { @@ -51,8 +51,8 @@ "repositoryURL": "https://github.com/kylef/Spectre.git", "state": { "branch": null, - "revision": "f79d4ecbf8bc4e1579fbd86c3e1d652fb6876c53", - "version": "0.9.2" + "revision": "26cc5e9ae0947092c7139ef7ba612e34646086c7", + "version": "0.10.1" } }, { @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/jakeheis/SwiftCLI.git", "state": { "branch": null, - "revision": "2816678bcc37f4833d32abeddbdf5e757fa891d8", - "version": "6.0.2" + "revision": "2e949055d9797c1a6bddcda0e58dada16cc8e970", + "version": "6.0.3" } }, { @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/tuist/XcodeProj.git", "state": { "branch": null, - "revision": "8e83191dba8bcbfc0be4d7c48bf1e02e7fedc88c", - "version": "8.2.0" + "revision": "446f3a0db73e141c7f57e26fcdb043096b1db52c", + "version": "8.3.1" } }, { diff --git a/Package.swift b/Package.swift index 04715b575..d4cc52018 100644 --- a/Package.swift +++ b/Package.swift @@ -11,13 +11,13 @@ let package = Package( .library(name: "ProjectSpec", targets: ["ProjectSpec"]), ], dependencies: [ - .package(url: "https://github.com/kylef/PathKit.git", from: "1.0.0"), + .package(url: "https://github.com/kylef/PathKit.git", from: "1.0.1"), .package(url: "https://github.com/jpsim/Yams.git", from: "4.0.0"), .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.9.2"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.2.0"), - .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.0"), + .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.3.1"), + .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.3"), .package(url: "https://github.com/mxcl/Version", from: "2.0.0"), .package(url: "https://github.com/SwiftDocOrg/GraphViz.git", .exact("0.2.0")), ], diff --git a/Tests/Fixtures/TestProject/carthage_dynamic.xcconfig b/Tests/Fixtures/TestProject/carthage_dynamic.xcconfig index 1207c460d..fc72c48c0 100644 --- a/Tests/Fixtures/TestProject/carthage_dynamic.xcconfig +++ b/Tests/Fixtures/TestProject/carthage_dynamic.xcconfig @@ -1 +1 @@ -#include "xcode12_workaround.xcconfig" +#include "xcode12_and_13_workaround.xcconfig" diff --git a/Tests/Fixtures/TestProject/carthage_static.xcconfig b/Tests/Fixtures/TestProject/carthage_static.xcconfig index 5248a0506..f1b875b96 100644 --- a/Tests/Fixtures/TestProject/carthage_static.xcconfig +++ b/Tests/Fixtures/TestProject/carthage_static.xcconfig @@ -1,2 +1,2 @@ -#include "xcode12_workaround.xcconfig" +#include "xcode12_and_13_workaround.xcconfig" MACH_O_TYPE = staticlib diff --git a/Tests/Fixtures/TestProject/fixtures.xcconfig b/Tests/Fixtures/TestProject/fixtures.xcconfig index 1372a09ff..8f9d84d4c 100644 --- a/Tests/Fixtures/TestProject/fixtures.xcconfig +++ b/Tests/Fixtures/TestProject/fixtures.xcconfig @@ -1,4 +1,4 @@ -#include "xcode12_workaround.xcconfig" +#include "xcode12_and_13_workaround.xcconfig" // Common settings for fixtures CODE_SIGN_IDENTITY = diff --git a/Tests/Fixtures/TestProject/xcode12_workaround.xcconfig b/Tests/Fixtures/TestProject/xcode12_and_13_workaround.xcconfig similarity index 76% rename from Tests/Fixtures/TestProject/xcode12_workaround.xcconfig rename to Tests/Fixtures/TestProject/xcode12_and_13_workaround.xcconfig index 4585c89f8..d89990040 100644 --- a/Tests/Fixtures/TestProject/xcode12_workaround.xcconfig +++ b/Tests/Fixtures/TestProject/xcode12_and_13_workaround.xcconfig @@ -6,4 +6,5 @@ EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8 EXCLUDED_ARCHS_1200=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)) +EXCLUDED_ARCHS_1300=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)) EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS_$(XCODE_VERSION_MAJOR)) From abb18642bac70eafd2cdc98741719aa45f162cf9 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Fri, 24 Sep 2021 09:12:09 +1000 Subject: [PATCH 10/55] Update to 2.25.0 --- Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9f5dad1d1..795671190 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.24.0 +VERSION = 2.25.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 5b4d507c6..746e00258 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.24.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.25.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index b952f7af6..2de4bb426 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.24.0") +let version = Version("2.25.0") let cli = XcodeGenCLI(version: version) cli.execute() From c8b2a4ac8a495f984ce7a321afdba19a8e9d436d Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Fri, 24 Sep 2021 09:12:56 +1000 Subject: [PATCH 11/55] update changelog --- CHANGELOG.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 908864e4e..1b271e332 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,6 @@ ## Next Version -### Fixed - -- Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole - ## 2.25.0 ### Added @@ -16,6 +12,7 @@ - Fix broken codesign option for bundle dependency [#1104](https://github.com/yonaskolb/XcodeGen/pull/1104) @kateinoigakukun - Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad - Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz +- Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) From 1d3412e1b60247aa615c077c9eee4549b566218e Mon Sep 17 00:00:00 2001 From: Yoshinori Imajo Date: Sun, 3 Oct 2021 09:57:24 +0900 Subject: [PATCH 12/55] Fix Graphviz on Mac URL in README. (#1134) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 746e00258..ca78aaf0d 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ To a file: xcodegen dump --type graphviz --file Graph.viz ``` -During implementation, `graphviz` formatting was validated using [GraphvizOnline](https://dreampuf.github.io/GraphvizOnline/), [WebGraphviz](http://www.webgraphviz.com), and [Graphviz on MacOS](graphviz.org). +During implementation, `graphviz` formatting was validated using [GraphvizOnline](https://dreampuf.github.io/GraphvizOnline/), [WebGraphviz](http://www.webgraphviz.com), and [Graphviz on MacOS](https://graphviz.org). ## Editing From 10fb43137b3d1f44e2d1d4fafa772a946bafb8c7 Mon Sep 17 00:00:00 2001 From: Paul Taykalo Date: Fri, 8 Oct 2021 01:20:19 +0300 Subject: [PATCH 13/55] Speed up search by using parallel Glob and Binary Search for including files checks (#1122) * Use binary searchi for Checking if path is included in included files * Do not run glob in parallel on Linux systems --- CHANGELOG.md | 4 + Sources/XcodeGenCore/ArrayExtensions.swift | 79 +++++++++++++++++++ Sources/XcodeGenCore/Glob.swift | 29 ++++--- Sources/XcodeGenKit/SourceGenerator.swift | 22 +++--- .../ArrayExtensionsTests.swift | 40 ++++++++++ 5 files changed, 155 insertions(+), 19 deletions(-) create mode 100644 Sources/XcodeGenCore/ArrayExtensions.swift create mode 100644 Tests/XcodeGenCoreTests/ArrayExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b271e332..68b1b5e8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Changed + +- Speed up source inclusion checking for big projects [#1122](https://github.com/yonaskolb/XcodeGen/pull/1122) @PaulTaykalo + ## 2.25.0 ### Added diff --git a/Sources/XcodeGenCore/ArrayExtensions.swift b/Sources/XcodeGenCore/ArrayExtensions.swift new file mode 100644 index 000000000..52c87ff77 --- /dev/null +++ b/Sources/XcodeGenCore/ArrayExtensions.swift @@ -0,0 +1,79 @@ +import Foundation + +public extension Array { + + func parallelMap(transform: (Element) -> T) -> [T] { + var result = ContiguousArray(repeating: nil, count: count) + return result.withUnsafeMutableBufferPointer { buffer in + DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in + buffer[idx] = transform(self[idx]) + } + return buffer.map { $0! } + } + } +} + +/// Holds a sorted array, created from specified sequence +/// This structure is needed for the cases, when some part of application requires array to be sorted, but don't trust any inputs :) +public struct SortedArray { + public let value: Array + public init(_ value: S) where S.Element == T { + self.value = value.sorted() + } +} + +public extension SortedArray { + /// Returns the first index in which an element of the collection satisfies the given predicate. + /// The collection assumed to be sorted. If collection is not have sorted values the result is undefined. + /// + /// The idea is to get first index of a function for which the given predicate evaluates to true. + /// + /// let values = [1,2,3,4,5] + /// let idx = values.firstIndexAssumingSorted(where: { $0 > 3 }) + /// + /// // false, false, false, true, true + /// // ^ + /// // therefore idx == 3 + /// + /// - Parameter predicate: A closure that takes an element as its argument + /// and returns a Boolean value that indicates whether the passed element + /// represents a match. + /// + /// - Returns: The index of the first element for which `predicate` returns + /// `true`. If no elements in the collection satisfy the given predicate, + /// returns `nil`. + /// + /// - Complexity: O(log(*n*)), where *n* is the length of the collection. + @inlinable + func firstIndex(where predicate: (T) throws -> Bool) rethrows -> Int? { + // Predicate should divide a collection to two pairs of values + // "bad" values for which predicate returns `false`` + // "good" values for which predicate return `true` + // false false false false false true true true + // ^ + // The idea is to get _first_ index which for which the predicate returns `true` + let lastIndex = value.count + + // The index that represents where bad values start + var badIndex = -1 + + // The index that represents where good values start + var goodIndex = lastIndex + var midIndex = (badIndex + goodIndex) / 2 + + while badIndex + 1 < goodIndex { + if try predicate(value[midIndex]) { + goodIndex = midIndex + } else { + badIndex = midIndex + } + midIndex = (badIndex + goodIndex) / 2 + } + + // We're out of bounds, no good items in array + if midIndex == lastIndex || goodIndex == lastIndex { + return nil + } + return goodIndex + } +} diff --git a/Sources/XcodeGenCore/Glob.swift b/Sources/XcodeGenCore/Glob.swift index b263cf5d3..596e986c7 100644 --- a/Sources/XcodeGenCore/Glob.swift +++ b/Sources/XcodeGenCore/Glob.swift @@ -89,15 +89,13 @@ public class Glob: Collection { } let patterns = behavior.supportsGlobstar ? expandGlobstar(pattern: adjustedPattern) : [adjustedPattern] - - for pattern in patterns { - var gt = glob_t() - if executeGlob(pattern: pattern, gt: >) { - populateFiles(gt: gt, includeFiles: includeFiles) - } - - globfree(>) - } + + #if os(macOS) + paths = patterns.parallelMap { paths(usingPattern: $0, includeFiles: includeFiles) }.flatMap { $0 } + #else + // Parallel invocations of Glob on Linux seems to be causing unexpected crashes + paths = patterns.map { paths(usingPattern: $0, includeFiles: includeFiles) }.flatMap { $0 } + #endif paths = Array(Set(paths)).sorted { lhs, rhs in lhs.compare(rhs) != ComparisonResult.orderedDescending @@ -209,7 +207,17 @@ public class Glob: Collection { isDirectoryCache.removeAll() } - private func populateFiles(gt: glob_t, includeFiles: Bool) { + private func paths(usingPattern pattern: String, includeFiles: Bool) -> [String] { + var gt = glob_t() + defer { globfree(>) } + if executeGlob(pattern: pattern, gt: >) { + return populateFiles(gt: gt, includeFiles: includeFiles) + } + return [] + } + + private func populateFiles(gt: glob_t, includeFiles: Bool) -> [String] { + var paths = [String]() let includeDirectories = behavior.includesDirectoriesInResults #if os(macOS) @@ -229,6 +237,7 @@ public class Glob: Collection { paths.append(path) } } + return paths } } diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index c3987b743..c7667cf6e 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -367,19 +367,23 @@ class SourceGenerator { } /// Checks whether the path is not in any default or TargetSource excludes - func isIncludedPath(_ path: Path, excludePaths: Set, includePaths: Set) -> Bool { - !defaultExcludedFiles.contains(where: { path.lastComponent.contains($0) }) + func isIncludedPath(_ path: Path, excludePaths: Set, includePaths: SortedArray) -> Bool { + return !defaultExcludedFiles.contains(where: { path.lastComponent == $0 }) && !(path.extension.map(defaultExcludedExtensions.contains) ?? false) && !excludePaths.contains(path) // If includes is empty, it's included. If it's not empty, the path either needs to match exactly, or it needs to be a direct parent of an included path. - && (includePaths.isEmpty || includePaths.contains(where: { includedFile in - if path == includedFile { return true } - return includedFile.description.contains(path.description) - })) + && (includePaths.value.isEmpty || _isIncludedPathSorted(path, sortedPaths: includePaths)) } + + private func _isIncludedPathSorted(_ path: Path, sortedPaths: SortedArray) -> Bool { + guard let idx = sortedPaths.firstIndex(where: { $0 >= path }) else { return false } + let foundPath = sortedPaths.value[idx] + return foundPath.description.hasPrefix(path.description) + } + /// Gets all the children paths that aren't excluded - private func getSourceChildren(targetSource: TargetSource, dirPath: Path, excludePaths: Set, includePaths: Set) throws -> [Path] { + private func getSourceChildren(targetSource: TargetSource, dirPath: Path, excludePaths: Set, includePaths: SortedArray) throws -> [Path] { try dirPath.children() .filter { if $0.isDirectory { @@ -408,7 +412,7 @@ class SourceGenerator { isBaseGroup: Bool, hasCustomParent: Bool, excludePaths: Set, - includePaths: Set, + includePaths: SortedArray, buildPhases: [Path: BuildPhaseSpec] ) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) { @@ -634,7 +638,7 @@ class SourceGenerator { isBaseGroup: true, hasCustomParent: hasCustomParent, excludePaths: excludePaths, - includePaths: includePaths, + includePaths: SortedArray(includePaths), buildPhases: buildPhases ) diff --git a/Tests/XcodeGenCoreTests/ArrayExtensionsTests.swift b/Tests/XcodeGenCoreTests/ArrayExtensionsTests.swift new file mode 100644 index 000000000..f15831477 --- /dev/null +++ b/Tests/XcodeGenCoreTests/ArrayExtensionsTests.swift @@ -0,0 +1,40 @@ +import XCTest +@testable import XcodeGenCore + +class ArrayExtensionsTests: XCTestCase { + + func testSearchingForFirstIndex() { + let array = SortedArray([1, 2, 3, 4 ,5]) + XCTAssertEqual(array.firstIndex(where: { $0 > 2 }), 2) + } + + func testIndexCannotBeFound() { + let array = SortedArray([1, 2, 3, 4, 5]) + XCTAssertEqual(array.firstIndex(where: { $0 > 10 }), nil) + } + + func testEmptyArray() { + let array = SortedArray([Int]()) + XCTAssertEqual(array.firstIndex(where: { $0 > 0 }), nil) + } + + func testSearchingReturnsFirstIndexWhenMultipleElementsHaveSameValue() { + let array = SortedArray([1, 2, 3, 3 ,3]) + XCTAssertEqual(array.firstIndex(where: { $0 == 3 }), 2) + } +} + + +class SortedArrayTests: XCTestCase { + + func testSortingOnInitialization() { + let array = [1, 5, 4, 2] + let sortedArray = SortedArray(array) + XCTAssertEqual([1, 2, 4, 5], sortedArray.value) + } + + func testEmpty() { + XCTAssertEqual([Int](), SortedArray([Int]()).value) + } + +} From c62277f150a0275e37f9f42a08e4e915686e78c7 Mon Sep 17 00:00:00 2001 From: Kristopher Jackson Date: Thu, 6 Jan 2022 18:09:58 -0600 Subject: [PATCH 14/55] Added location option to test target (#1153) * Added location option to test target * Updated XcodeProj * Updated packages * Removed extra toJSONValue() * Update Docs/ProjectSpec.md Co-authored-by: Yonas Kolb * Update Sources/ProjectSpec/Scheme.swift Co-authored-by: Yonas Kolb * Update Sources/ProjectSpec/Scheme.swift Co-authored-by: Yonas Kolb * Removed optional location * Renamed SimulateLocation to Location * Removed Location struct and just pass location string directly * Added tests for location with a test target * Added example of location inside test target to project.yml * Removed extra test target and add location to existing target * Updated App_Scheme.xcscheme Co-authored-by: Yonas Kolb --- CHANGELOG.md | 4 ++++ Docs/ProjectSpec.md | 1 + Package.resolved | 4 ++-- Package.swift | 2 +- Sources/ProjectSpec/Scheme.swift | 9 ++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 22 ++++++++++++++++--- .../xcschemes/App_Scheme.xcscheme | 4 ++++ Tests/Fixtures/TestProject/project.yml | 1 + Tests/ProjectSpecTests/SpecLoadingTests.swift | 4 ++++ .../SchemeGeneratorTests.swift | 14 ++++++++++-- 10 files changed, 57 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b1b5e8f..62f72d742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Added + +- Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack + ### Changed - Speed up source inclusion checking for big projects [#1122](https://github.com/yonaskolb/XcodeGen/pull/1122) @PaulTaykalo diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index c99f14628..1874c94d5 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -834,6 +834,7 @@ A multiline script can be written using the various YAML multiline methods, for - [x] **name**: **String** - The name of the target - [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false - [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false +- [ ] **location**: **String** - GPX file or predefined value for simulating location. See [Simulate Location](#simulate-location) for location examples. - [ ] **skipped**: **Bool** - Whether to skip all of the test target tests. Defaults to false - [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty - [ ] **selectedTests**: **[String]** - List of tests in the test target to whitelist and select. Defaults to empty. This will override `skippedTests` if provided diff --git a/Package.resolved b/Package.resolved index 4d75c7312..e883890e9 100644 --- a/Package.resolved +++ b/Package.resolved @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/tuist/XcodeProj.git", "state": { "branch": null, - "revision": "446f3a0db73e141c7f57e26fcdb043096b1db52c", - "version": "8.3.1" + "revision": "aa2a42c7a744ca18b5918771fdd6cf40f9753db5", + "version": "8.6.0" } }, { diff --git a/Package.swift b/Package.swift index d4cc52018..c1d72975f 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.9.2"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.3.1"), + .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.6.0"), .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.3"), .package(url: "https://github.com/mxcl/Version", from: "2.0.0"), .package(url: "https://github.com/SwiftDocOrg/GraphViz.git", .exact("0.2.0")), diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index ed921c89d..25ce697cc 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -184,6 +184,7 @@ public struct Scheme: Equatable { public var deleteScreenshotsWhenEachTestSucceeds: Bool public struct TestTarget: Equatable, ExpressibleByStringLiteral { + public static let randomExecutionOrderDefault = false public static let parallelizableDefault = false @@ -191,6 +192,7 @@ public struct Scheme: Equatable { public let targetReference: TargetReference public var randomExecutionOrder: Bool public var parallelizable: Bool + public var location: String? public var skipped: Bool public var skippedTests: [String] public var selectedTests: [String] @@ -199,6 +201,7 @@ public struct Scheme: Equatable { targetReference: TargetReference, randomExecutionOrder: Bool = randomExecutionOrderDefault, parallelizable: Bool = parallelizableDefault, + location: String? = nil, skipped: Bool = false, skippedTests: [String] = [], selectedTests: [String] = [] @@ -206,6 +209,7 @@ public struct Scheme: Equatable { self.targetReference = targetReference self.randomExecutionOrder = randomExecutionOrder self.parallelizable = parallelizable + self.location = location self.skipped = skipped self.skippedTests = skippedTests self.selectedTests = selectedTests @@ -216,6 +220,7 @@ public struct Scheme: Equatable { targetReference = try TargetReference(value) randomExecutionOrder = false parallelizable = false + location = nil skipped = false skippedTests = [] selectedTests = [] @@ -536,6 +541,7 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { targetReference = try TargetReference(jsonDictionary.json(atKeyPath: "name")) randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault + location = jsonDictionary.json(atKeyPath: "location") ?? nil skipped = jsonDictionary.json(atKeyPath: "skipped") ?? false skippedTests = jsonDictionary.json(atKeyPath: "skippedTests") ?? [] selectedTests = jsonDictionary.json(atKeyPath: "selectedTests") ?? [] @@ -559,6 +565,9 @@ extension Scheme.Test.TestTarget: JSONEncodable { if parallelizable != Scheme.Test.TestTarget.parallelizableDefault { dict["parallelizable"] = parallelizable } + if let location = location { + dict["location"] = location + } if skipped { dict["skipped"] = skipped } diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index 67f681964..e5fa2d54b 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -187,12 +187,28 @@ public class SchemeGenerator { runPostActionsOnFailure: scheme.build.runPostActionsOnFailure ) - let testables = zip(testTargets, testBuildTargetEntries).map { testTarget, testBuilEntries in - XCScheme.TestableReference( + let testables: [XCScheme.TestableReference] = zip(testTargets, testBuildTargetEntries).map { testTarget, testBuildEntries in + + var locationScenarioReference: XCScheme.LocationScenarioReference? + if var location = testTarget.location { + + if location.contains(".gpx") { + var path = Path(components: [project.options.schemePathPrefix, location]) + path = path.simplifyingParentDirectoryReferences() + location = path.string + } + + let referenceType = location.contains(".gpx") ? "0" : "1" + locationScenarioReference = XCScheme.LocationScenarioReference(identifier: location, referenceType: referenceType) + + } + + return XCScheme.TestableReference( skipped: testTarget.skipped, parallelizable: testTarget.parallelizable, randomExecutionOrdering: testTarget.randomExecutionOrder, - buildableReference: testBuilEntries.buildableReference, + buildableReference: testBuildEntries.buildableReference, + locationScenarioReference: locationScenarioReference, skippedTests: testTarget.skippedTests.map(XCScheme.TestItem.init), selectedTests: testTarget.selectedTests.map(XCScheme.TestItem.init), useTestSelectionWhitelist: !testTarget.selectedTests.isEmpty ? true : nil diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme index 47aae2213..5aa4973cb 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme @@ -53,6 +53,10 @@ BlueprintName = "App_iOS_Tests" ReferencedContainer = "container:Project.xcodeproj"> + + diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 85662468a..ff6d045c5 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -426,6 +426,7 @@ schemes: - name: App_iOS_Tests parallelizable: true randomExecutionOrder: true + location: New York, NY, USA customLLDBInit: ${SRCROOT}/.lldbinit targetTemplates: MyTemplate: diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift index 2282a8fa1..d1c0e6c68 100644 --- a/Tests/ProjectSpecTests/SpecLoadingTests.swift +++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift @@ -790,6 +790,7 @@ class SpecLoadingTests: XCTestCase { "name": "ExternalProject/Target2", "parallelizable": true, "skipped": true, + "location": "test.gpx", "randomExecutionOrder": true, "skippedTests": ["Test/testExample()"], ], @@ -836,6 +837,7 @@ class SpecLoadingTests: XCTestCase { targetReference: "ExternalProject/Target2", randomExecutionOrder: true, parallelizable: true, + location: "test.gpx", skipped: true, skippedTests: ["Test/testExample()"] ), @@ -856,6 +858,7 @@ class SpecLoadingTests: XCTestCase { [ "name": "ExternalProject/Target2", "parallelizable": true, + "location": "New York, NY, USA", "randomExecutionOrder": true, "selectedTests": ["Test/testExample()"], ], @@ -877,6 +880,7 @@ class SpecLoadingTests: XCTestCase { targetReference: "ExternalProject/Target2", randomExecutionOrder: true, parallelizable: true, + location: "New York, NY, USA", selectedTests: ["Test/testExample()"] ), ] diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index 3c27b8a91..b78a61774 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -49,11 +49,14 @@ class SchemeGeneratorTests: XCTestCase { let preAction = Scheme.ExecutionAction(name: "Script", script: "echo Starting", settingsTarget: app.name) let simulateLocation = Scheme.SimulateLocation(allow: true, defaultLocation: "New York, NY, USA") let storeKitConfiguration = "Configuration.storekit" - let scheme = Scheme( + let scheme = try Scheme( name: "MyScheme", build: Scheme.Build(targets: [buildTarget], preActions: [preAction]), run: Scheme.Run(config: "Debug", askForAppToLaunch: true, launchAutomaticallySubstyle: "2", simulateLocation: simulateLocation, storeKitConfiguration: storeKitConfiguration, customLLDBInit: "/sample/.lldbinit"), - test: Scheme.Test(config: "Debug", customLLDBInit: "/test/.lldbinit"), + test: Scheme.Test(config: "Debug", targets: [ + Scheme.Test.TestTarget(targetReference: TargetReference(framework.name), location: "test.gpx"), + Scheme.Test.TestTarget(targetReference: TargetReference(framework.name), location: "New York, NY, USA") + ], customLLDBInit: "/test/.lldbinit"), profile: Scheme.Profile(config: "Release", askForAppToLaunch: true) ) let project = Project( @@ -109,6 +112,13 @@ class SchemeGeneratorTests: XCTestCase { try expect(xcscheme.launchAction?.customLLDBInitFile) == "/sample/.lldbinit" try expect(xcscheme.testAction?.customLLDBInitFile) == "/test/.lldbinit" try expect(xcscheme.testAction?.systemAttachmentLifetime).to.beNil() + + try expect(xcscheme.testAction?.testables[0].locationScenarioReference?.referenceType) == "0" + try expect(xcscheme.testAction?.testables[0].locationScenarioReference?.identifier) == "../test.gpx" + + try expect(xcscheme.testAction?.testables[1].locationScenarioReference?.referenceType) == "1" + try expect(xcscheme.testAction?.testables[1].locationScenarioReference?.identifier) == "New York, NY, USA" + } let frameworkTarget = Scheme.BuildTarget(target: .local(framework.name), buildTypes: [.archiving]) From 62b9bea413b3d016108d1e5a65dcf953303c1e3b Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Mon, 7 Feb 2022 09:25:24 +1100 Subject: [PATCH 15/55] ignore vscode --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index caf10c284..1f55464ba 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ xcuserdata *.xcuserstate XcodeGen.xcodeproj xcodegen.zip +.vscode/launch.json From 9bd8ad1e4ae19de6c77e4f326e6a67dc8badec41 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Mon, 7 Feb 2022 09:27:20 +1100 Subject: [PATCH 16/55] Update to 2.26.0 --- CHANGELOG.md | 4 ++++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62f72d742..ab73aaf2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.26.0 + ### Added - Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack @@ -10,6 +12,8 @@ - Speed up source inclusion checking for big projects [#1122](https://github.com/yonaskolb/XcodeGen/pull/1122) @PaulTaykalo +[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.25.0...2.26.0) + ## 2.25.0 ### Added diff --git a/Makefile b/Makefile index 795671190..f3dd42b2a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.25.0 +VERSION = 2.26.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index ca78aaf0d..6b036a520 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.25.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.26.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index 2de4bb426..8ba636bf8 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.25.0") +let version = Version("2.26.0") let cli = XcodeGenCLI(version: version) cli.execute() From d218ada92fbcd68127c240418968c3893f70714e Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Wed, 9 Feb 2022 11:30:23 +1100 Subject: [PATCH 17/55] fix archive if repo path has spaces --- Makefile | 2 +- scripts/archive.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f3dd42b2a..aa515b3d4 100644 --- a/Makefile +++ b/Makefile @@ -46,4 +46,4 @@ brew: brew bump-formula-pr --url=$(RELEASE_TAR) XcodeGen archive: build - ./scripts/archive.sh $(EXECUTABLE_PATH) + ./scripts/archive.sh "$(EXECUTABLE_PATH)" diff --git a/scripts/archive.sh b/scripts/archive.sh index ad3355072..0a9ebb585 100755 --- a/scripts/archive.sh +++ b/scripts/archive.sh @@ -10,7 +10,7 @@ LICENSE=LICENSE # copy mkdir -p $BINDIR -cp -f $1 $BINDIR +cp -f "$1" $BINDIR mkdir -p $SHAREDIR cp -R SettingPresets $SHAREDIR/SettingPresets From a10c7c4c24f6f5b6acccafb7a5bb57a33068a8a7 Mon Sep 17 00:00:00 2001 From: Vladislav Lisyanskiy Date: Sun, 6 Mar 2022 10:32:35 +0300 Subject: [PATCH 18/55] Fixed Glob crash (#1181) --- CHANGELOG.md | 4 ++++ Sources/XcodeGenCore/Atomic.swift | 27 +++++++++++++++++++++++++++ Sources/XcodeGenCore/Glob.swift | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Sources/XcodeGenCore/Atomic.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index ab73aaf2b..c5394630a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Fixed + +- Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x + ## 2.26.0 ### Added diff --git a/Sources/XcodeGenCore/Atomic.swift b/Sources/XcodeGenCore/Atomic.swift new file mode 100644 index 000000000..c7911ca42 --- /dev/null +++ b/Sources/XcodeGenCore/Atomic.swift @@ -0,0 +1,27 @@ +// +// Atomic.swift +// +// +// Created by Vladislav Lisianskii on 23.02.2022. +// + +import Foundation + +@propertyWrapper +struct Atomic { + private let queue = DispatchQueue(label: "com.xcodegencore.atomic") + private var value: Value + + init(wrappedValue: Value) { + self.value = wrappedValue + } + + var wrappedValue: Value { + get { + return queue.sync { value } + } + set { + queue.sync { value = newValue } + } + } +} diff --git a/Sources/XcodeGenCore/Glob.swift b/Sources/XcodeGenCore/Glob.swift index 596e986c7..e3025eab7 100644 --- a/Sources/XcodeGenCore/Glob.swift +++ b/Sources/XcodeGenCore/Glob.swift @@ -57,7 +57,7 @@ public class Glob: Collection { public static let defaultBlacklistedDirectories = ["node_modules", "Pods"] - private var isDirectoryCache = [String: Bool]() + @Atomic private var isDirectoryCache = [String: Bool]() public let behavior: Behavior public let blacklistedDirectories: [String] From 3b5ca91b76bbd482e602ffd902872d14a8e11074 Mon Sep 17 00:00:00 2001 From: Gabriel Lanata Date: Wed, 16 Mar 2022 21:56:03 -0700 Subject: [PATCH 19/55] Add coverage targets for target schemes (#1189) * Changes * Tests and docs * Update fixtures * Update CHANGELOG.md Co-authored-by: Yonas Kolb Co-authored-by: Yonas Kolb --- CHANGELOG.md | 1 + Docs/ProjectSpec.md | 4 ++++ Sources/ProjectSpec/TargetScheme.swift | 17 +++++++++++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 1 + .../xcschemes/App_iOS Production.xcscheme | 11 ++++++++++- .../xcschemes/App_iOS Staging.xcscheme | 11 ++++++++++- .../xcschemes/App_iOS Test.xcscheme | 11 ++++++++++- Tests/Fixtures/TestProject/project.yml | 2 ++ Tests/ProjectSpecTests/ProjectSpecTests.swift | 1 + Tests/ProjectSpecTests/SpecLoadingTests.swift | 2 ++ .../SchemeGeneratorTests.swift | 19 +++++++++++++++++++ 11 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5394630a..0093bf6b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Added - Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ### Changed diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 1874c94d5..700fb8009 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -653,6 +653,7 @@ This is a convenience used to automatically generate schemes for a target based - [x] **configVariants**: **[String]** - This generates a scheme for each entry, using configs that contain the name with debug and release variants. This is useful for having different environment schemes. - [ ] **testTargets**: **[[Test Target](#test-target)]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false +- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) - [ ] **disableMainThreadChecker**: **Bool** - a boolean that indicates if this scheme should disable the Main Thread Checker. This defaults to false - [ ] **stopOnEveryMainThreadCheckerIssue**: **Bool** - a boolean that indicates if this scheme should stop at every Main Thread Checker issue. This defaults to false - [ ] **buildImplicitDependencies**: **Bool** - Flag to determine if Xcode should build implicit dependencies of this scheme. By default this is `true` if not set. @@ -691,6 +692,9 @@ targets: - Staging - Production gatherCoverageData: true + coverageTargets: + - MyTarget1 + - ExternalTarget/OtherTarget1 commandLineArguments: "-MyEnabledArg": true "-MyDisabledArg": false diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 1beedb6a9..289bf5e30 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -11,6 +11,7 @@ public struct TargetScheme: Equatable { public var testTargets: [Scheme.Test.TestTarget] public var configVariants: [String] public var gatherCoverageData: Bool + public var coverageTargets: [TargetReference] public var storeKitConfiguration: String? public var language: String? public var region: String? @@ -26,6 +27,7 @@ public struct TargetScheme: Equatable { testTargets: [Scheme.Test.TestTarget] = [], configVariants: [String] = [], gatherCoverageData: Bool = gatherCoverageDataDefault, + coverageTargets: [TargetReference] = [], storeKitConfiguration: String? = nil, language: String? = nil, region: String? = nil, @@ -40,6 +42,7 @@ public struct TargetScheme: Equatable { self.testTargets = testTargets self.configVariants = configVariants self.gatherCoverageData = gatherCoverageData + self.coverageTargets = coverageTargets self.storeKitConfiguration = storeKitConfiguration self.language = language self.region = region @@ -69,6 +72,19 @@ extension TargetScheme: JSONObjectConvertible { } else { testTargets = [] } + + if let targets = jsonDictionary["coverageTargets"] as? [Any] { + coverageTargets = try targets.compactMap { target in + if let string = target as? String { + return try TargetReference(string) + } else { + return nil + } + } + } else { + coverageTargets = [] + } + configVariants = jsonDictionary.json(atKeyPath: "configVariants") ?? [] gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? TargetScheme.gatherCoverageDataDefault storeKitConfiguration = jsonDictionary.json(atKeyPath: "storeKitConfiguration") @@ -88,6 +104,7 @@ extension TargetScheme: JSONEncodable { public func toJSONValue() -> Any { var dict: [String: Any] = [ "configVariants": configVariants, + "coverageTargets": coverageTargets.map { $0.reference }, "commandLineArguments": commandLineArguments, "testTargets": testTargets.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index e5fa2d54b..fa008bb7b 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -413,6 +413,7 @@ extension Scheme { test: .init( config: debugConfig, gatherCoverageData: targetScheme.gatherCoverageData, + coverageTargets: targetScheme.coverageTargets, disableMainThreadChecker: targetScheme.disableMainThreadChecker, commandLineArguments: targetScheme.commandLineArguments, targets: targetScheme.testTargets, diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme index d06a2910a..479690500 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme @@ -28,7 +28,7 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "NO" + onlyGenerateCoverageForSpecifiedTargets = "YES" shouldUseLaunchSchemeArgsEnv = "NO" disableMainThreadChecker = "YES"> @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + Date: Thu, 17 Mar 2022 15:57:22 +1100 Subject: [PATCH 20/55] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0093bf6b7..2f6917e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Added + +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata + ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x @@ -11,7 +15,6 @@ ### Added - Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ### Changed From 7b9d95ab4cb73b1fc206914fbeed7ee75e2f4f73 Mon Sep 17 00:00:00 2001 From: Evan Coleman Date: Sat, 19 Mar 2022 23:19:23 -0400 Subject: [PATCH 21/55] Skip compile sources for watch apps (#1185) * Skip compile sources build phase for watch2 apps if empty * add changelog entry * Fix tests Co-authored-by: Yonas Kolb --- CHANGELOG.md | 9 +++++---- Sources/ProjectSpec/XCProjExtensions.swift | 4 ++-- .../TestProject/Project.xcodeproj/project.pbxproj | 8 -------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6917e69..21de2b776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,14 @@ ## Next Version -### Added - -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata - ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x +- Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman + +### Added + +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ## 2.26.0 diff --git a/Sources/ProjectSpec/XCProjExtensions.swift b/Sources/ProjectSpec/XCProjExtensions.swift index bf3d36d21..9bee91be9 100644 --- a/Sources/ProjectSpec/XCProjExtensions.swift +++ b/Sources/ProjectSpec/XCProjExtensions.swift @@ -48,8 +48,8 @@ extension PBXProductType { public var canSkipCompileSourcesBuildPhase: Bool { switch self { - case .bundle, .stickerPack, .messagesApplication: - // Bundles, sticker packs and simple messages applications without sources should not include a + case .bundle, .watch2App, .stickerPack, .messagesApplication: + // Bundles, watch apps, sticker packs and simple messages applications without sources should not include a // compile sources build phase. Doing so can cause Xcode to produce an error on build. return true default: diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index c0344eb31..2f440618d 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -1697,7 +1697,6 @@ isa = PBXNativeTarget; buildConfigurationList = 6B5C5F08C0EF06457756E379 /* Build configuration list for PBXNativeTarget "App_watchOS" */; buildPhases = ( - 91C895DE8170C96A75D29426 /* Sources */, B7B71FA7D279029BF7A7FC7C /* Resources */, C765431E5FF4B02F59DE79B0 /* Embed App Extensions */, ); @@ -2706,13 +2705,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 91C895DE8170C96A75D29426 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 96BB43F4706B031DA45166E8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; From e77caa8a4052b394d09948801dc5883f0a325e16 Mon Sep 17 00:00:00 2001 From: Christian Huck Date: Sun, 20 Mar 2022 04:20:37 +0100 Subject: [PATCH 22/55] add .gyb as an accepted source file (#1191) * add .gyb to source files * Update CHANGELOG.md Co-authored-by: Christian Huck --- CHANGELOG.md | 2 ++ Sources/ProjectSpec/FileType.swift | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21de2b776..3672aee2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata +- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian + ## 2.26.0 ### Added diff --git a/Sources/ProjectSpec/FileType.swift b/Sources/ProjectSpec/FileType.swift index 372bc79d8..d106b2857 100644 --- a/Sources/ProjectSpec/FileType.swift +++ b/Sources/ProjectSpec/FileType.swift @@ -75,6 +75,7 @@ extension FileType { // sources "swift": FileType(buildPhase: .sources), + "gyb": FileType(buildPhase: .sources), "m": FileType(buildPhase: .sources), "mm": FileType(buildPhase: .sources), "cpp": FileType(buildPhase: .sources), From 146eaadaf3aed2242d71c8531a38c153520d7fa9 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sun, 20 Mar 2022 14:20:53 +1100 Subject: [PATCH 23/55] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3672aee2c..d9af32ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ ### Added - Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata - - Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian ## 2.26.0 From 245f17117abe10a4d823c917fbed7dceaff1a851 Mon Sep 17 00:00:00 2001 From: "freddi(Yuki Aki)" Date: Sun, 20 Mar 2022 12:27:29 +0900 Subject: [PATCH 24/55] Support test target for local Swift Package (#1169) * support local Swift Package test case into test scheme * update test * add test * update CHABGELOG.md * Update CHANGELOG.md * revert resolved package test * Update Sources/XcodeGenKit/SchemeGenerator.swift Co-authored-by: Kohki Miki * make TargetReference convert from new JSON format * add .package for location of target reference * receive target reference format at target of scheme * update test * update XcodeProj * add test and fix small bugs * update docs * support multiple style of coverageTargets * add edge case of parsing test targets * fix docs * Update Docs/ProjectSpec.md Co-authored-by: Yonas Kolb * create TestableTargetReference for not making API complex * fix code format * fix parameter name to Testable Target Reference * support directly writing key of Testable Target Reference * fix compile error in build Co-authored-by: Kohki Miki Co-authored-by: Yonas Kolb --- CHANGELOG.md | 2 + Docs/ProjectSpec.md | 22 +++- Sources/ProjectSpec/Project.swift | 4 + Sources/ProjectSpec/Scheme.swift | 47 ++++++-- Sources/ProjectSpec/SpecValidation.swift | 18 +++ Sources/ProjectSpec/SpecValidationError.swift | 3 + Sources/ProjectSpec/TargetReference.swift | 4 +- Sources/ProjectSpec/TargetScheme.swift | 7 +- Sources/ProjectSpec/TestTargeReference.swift | 112 ++++++++++++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 29 ++++- .../xcshareddata/xcschemes/App.xcscheme | 20 ++++ Tests/Fixtures/SPM/project.yml | 7 +- .../SchemeGeneratorTests.swift | 37 +++++- 13 files changed, 284 insertions(+), 28 deletions(-) create mode 100644 Sources/ProjectSpec/TestTargeReference.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index d9af32ed9..eca47f8e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Change Log ## Next Version +#### Added +- Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit ### Fixed diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 700fb8009..70562385a 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -828,14 +828,22 @@ A multiline script can be written using the various YAML multiline methods, for ### Test Action - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file - [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true. - [ ] **deleteScreenshotsWhenEachTestSucceeds**: **Bool** - whether successful UI tests should cause automatically-captured screenshots to be deleted. If `captureScreenshotsAutomatically` is false, this value is ignored. This defaults to true. #### Test Target -- [x] **name**: **String** - The name of the target +A target can be one of a 2 types: + +- **name**: **String** - The name of the target. +- **target**: **[Testable Target Reference](#testable-target-reference)** - The information of the target. You can specify more detailed information than `name:`. + +As syntax suger, you can also specify **[Testable Target Reference](#testable-target-reference)** without `target`. + +#### Other Parameters + - [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false - [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false - [ ] **location**: **String** - GPX file or predefined value for simulating location. See [Simulate Location](#simulate-location) for location examples. @@ -843,6 +851,12 @@ A multiline script can be written using the various YAML multiline methods, for - [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty - [ ] **selectedTests**: **[String]** - List of tests in the test target to whitelist and select. Defaults to empty. This will override `skippedTests` if provided +#### Testable Target Reference +A Testable Target Reference can be one of 3 types: +- `package: {local-swift-package-name}/{target-name}`: Name of local swift package and its target. +- `local: {target-name}`: Name of local target. +- `project: {project-reference-name}/{target-name}`: Name of local swift package and its target. + ### Archive Action - [ ] **customArchiveName**: **String** - the custom name to give to the archive @@ -902,12 +916,16 @@ schemes: coverageTargets: - MyTarget1 - ExternalTarget/OtherTarget1 + - package: LocalPackage/TestTarget targets: - Tester1 - name: Tester2 parallelizable: true randomExecutionOrder: true skippedTests: [Test/testExample()] + - package: APIClient/APIClientTests + parallelizable: true + randomExecutionOrder: true environmentVariables: - variable: TEST_ENV_VAR value: VALUE diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 2d6842dcf..972daa01c 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -83,6 +83,10 @@ public struct Project: BuildSettingsContainer { targetsMap[targetName] } + public func getPackage(_ packageName: String) -> SwiftPackage? { + packages[packageName] + } + public func getAggregateTarget(_ targetName: String) -> AggregateTarget? { aggregateTargetsMap[targetName] } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 25ce697cc..73c762d62 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -169,7 +169,7 @@ public struct Scheme: Equatable { public var config: String? public var gatherCoverageData: Bool - public var coverageTargets: [TargetReference] + public var coverageTargets: [TestableTargetReference] public var disableMainThreadChecker: Bool public var commandLineArguments: [String: Bool] public var targets: [TestTarget] @@ -189,7 +189,7 @@ public struct Scheme: Equatable { public static let parallelizableDefault = false public var name: String { targetReference.name } - public let targetReference: TargetReference + public let targetReference: TestableTargetReference public var randomExecutionOrder: Bool public var parallelizable: Bool public var location: String? @@ -198,7 +198,7 @@ public struct Scheme: Equatable { public var selectedTests: [String] public init( - targetReference: TargetReference, + targetReference: TestableTargetReference, randomExecutionOrder: Bool = randomExecutionOrderDefault, parallelizable: Bool = parallelizableDefault, location: String? = nil, @@ -217,7 +217,7 @@ public struct Scheme: Equatable { public init(stringLiteral value: String) { do { - targetReference = try TargetReference(value) + targetReference = try TestableTargetReference(value) randomExecutionOrder = false parallelizable = false location = nil @@ -233,7 +233,7 @@ public struct Scheme: Equatable { public init( config: String, gatherCoverageData: Bool = gatherCoverageDataDefault, - coverageTargets: [TargetReference] = [], + coverageTargets: [TestableTargetReference] = [], disableMainThreadChecker: Bool = disableMainThreadCheckerDefault, randomExecutionOrder: Bool = false, parallelizable: Bool = false, @@ -331,10 +331,10 @@ public struct Scheme: Equatable { } public struct BuildTarget: Equatable, Hashable { - public var target: TargetReference + public var target: TestableTargetReference public var buildTypes: [BuildType] - public init(target: TargetReference, buildTypes: [BuildType] = BuildType.all) { + public init(target: TestableTargetReference, buildTypes: [BuildType] = BuildType.all) { self.target = target self.buildTypes = buildTypes } @@ -465,13 +465,28 @@ extension Scheme.Test: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { config = jsonDictionary.json(atKeyPath: "config") gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? Scheme.Test.gatherCoverageDataDefault - coverageTargets = try (jsonDictionary.json(atKeyPath: "coverageTargets") ?? []).map { try TargetReference($0) } + + if let coverages = jsonDictionary["coverageTargets"] as? [Any] { + coverageTargets = try coverages.compactMap { target in + if let string = target as? String { + return try TestableTargetReference(string) + } else if let dictionary = target as? JSONDictionary, + let target: TestableTargetReference = try? .init(jsonDictionary: dictionary) { + return target + } else { + return nil + } + } + } else { + coverageTargets = [] + } + disableMainThreadChecker = jsonDictionary.json(atKeyPath: "disableMainThreadChecker") ?? Scheme.Test.disableMainThreadCheckerDefault commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:] if let targets = jsonDictionary["targets"] as? [Any] { self.targets = try targets.compactMap { target in if let string = target as? String { - return try TestTarget(targetReference: TargetReference(string)) + return try TestTarget(targetReference: TestableTargetReference(string)) } else if let dictionary = target as? JSONDictionary { return try TestTarget(jsonDictionary: dictionary) } else { @@ -538,7 +553,17 @@ extension Scheme.Test: JSONEncodable { extension Scheme.Test.TestTarget: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { - targetReference = try TargetReference(jsonDictionary.json(atKeyPath: "name")) + if let name: String = jsonDictionary.json(atKeyPath: "name") { + targetReference = try TestableTargetReference(name) + } else if let local: String = jsonDictionary.json(atKeyPath: "local") { + self.targetReference = TestableTargetReference.local(local) + } else if let project: String = jsonDictionary.json(atKeyPath: "project") { + self.targetReference = TestableTargetReference.project(project) + } else if let package: String = jsonDictionary.json(atKeyPath: "package") { + self.targetReference = TestableTargetReference.package(package) + } else { + self.targetReference = try jsonDictionary.json(atKeyPath: "target") + } randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault location = jsonDictionary.json(atKeyPath: "location") ?? nil @@ -694,7 +719,7 @@ extension Scheme.Build: JSONObjectConvertible { } else { buildTypes = BuildType.all } - let target = try TargetReference(targetRepr) + let target = try TestableTargetReference(targetRepr) targets.append(Scheme.BuildTarget(target: target, buildTypes: buildTypes)) } self.targets = targets.sorted { $0.target.name < $1.target.name } diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index fd1049c6e..01caca589 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -119,6 +119,10 @@ extension Project { for testTarget in scheme.testTargets { if getTarget(testTarget.name) == nil { + // For test case of local Swift Package + if case .package(let name) = testTarget.targetReference.location, getPackage(name) != nil { + continue + } errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget.name)) } } @@ -243,4 +247,18 @@ extension Project { return nil } } + + /// Returns a descriptive error if the given target reference was invalid otherwise `nil`. + private func validationError(for testableTargetReference: TestableTargetReference, in scheme: Scheme, action: String) -> SpecValidationError.ValidationError? { + switch testableTargetReference.location { + case .local where getProjectTarget(testableTargetReference.name) == nil: + return .invalidSchemeTarget(scheme: scheme.name, target: testableTargetReference.name, action: action) + case .project(let project) where getProjectReference(project) == nil: + return .invalidProjectReference(scheme: scheme.name, reference: project) + case .package(let package) where getPackage(package) == nil: + return .invalidLocalPackage(package) + case .local, .project, .package: + return nil + } + } } diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index c19486526..f4025bbf8 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -20,6 +20,7 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidSchemeTarget(scheme: String, target: String, action: String) case invalidSchemeConfig(scheme: String, config: String) case invalidSwiftPackage(name: String, target: String) + case invalidPackageDependencyReference(name: String) case invalidLocalPackage(String) case invalidConfigFile(configFile: String, config: String) case invalidBuildSettingConfig(String) @@ -69,6 +70,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Target \(target.quoted) has an invalid package dependency \(name.quoted)" case let .invalidLocalPackage(path): return "Invalid local package \(path.quoted)" + case let .invalidPackageDependencyReference(name): + return "Package reference \(name) must be specified as package dependency, not target" case let .missingConfigForTargetScheme(target, configType): return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme" case let .missingDefaultConfig(name): diff --git a/Sources/ProjectSpec/TargetReference.swift b/Sources/ProjectSpec/TargetReference.swift index 1a64e258a..22da0a2e1 100644 --- a/Sources/ProjectSpec/TargetReference.swift +++ b/Sources/ProjectSpec/TargetReference.swift @@ -46,8 +46,8 @@ extension TargetReference: CustomStringConvertible { public var reference: String { switch location { case .local: return name - case .project(let projectPath): - return "\(projectPath)/\(name)" + case .project(let root): + return "\(root)/\(name)" } } diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 289bf5e30..136fd7965 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -62,9 +62,10 @@ extension TargetScheme: JSONObjectConvertible { if let targets = jsonDictionary["testTargets"] as? [Any] { testTargets = try targets.compactMap { target in if let string = target as? String { - return .init(targetReference: try TargetReference(string)) - } else if let dictionary = target as? JSONDictionary { - return try .init(jsonDictionary: dictionary) + return .init(targetReference: try TestableTargetReference(string)) + } else if let dictionary = target as? JSONDictionary, + let target: Scheme.Test.TestTarget = try? .init(jsonDictionary: dictionary) { + return target } else { return nil } diff --git a/Sources/ProjectSpec/TestTargeReference.swift b/Sources/ProjectSpec/TestTargeReference.swift new file mode 100644 index 000000000..17ea557bb --- /dev/null +++ b/Sources/ProjectSpec/TestTargeReference.swift @@ -0,0 +1,112 @@ +import Foundation +import JSONUtilities + +public struct TestableTargetReference: Hashable { + public var name: String + public var location: Location + + public var targetReference: TargetReference { + switch location { + case .local: + return TargetReference(name: name, location: .local) + case .project(let projectName): + return TargetReference(name: name, location: .project(projectName)) + case .package: + fatalError("Package target is only available for testable") + } + } + + public enum Location: Hashable { + case local + case project(String) + case package(String) + } + + public init(name: String, location: Location) { + self.name = name + self.location = location + } +} + +extension TestableTargetReference { + public init(_ string: String) throws { + let paths = string.split(separator: "/") + switch paths.count { + case 2: + location = .project(String(paths[0])) + name = String(paths[1]) + case 1: + location = .local + name = String(paths[0]) + default: + throw SpecParsingError.invalidTargetReference(string) + } + } + + public static func local(_ name: String) -> TestableTargetReference { + TestableTargetReference(name: name, location: .local) + } + + public static func project(_ name: String) -> TestableTargetReference { + let paths = name.split(separator: "/") + return TestableTargetReference(name: String(paths[1]), location: .project(String(paths[0]))) + } + + public static func package(_ name: String) -> TestableTargetReference { + let paths = name.split(separator: "/") + return TestableTargetReference(name: String(paths[1]), location: .package(String(paths[0]))) + } +} + +extension TestableTargetReference: ExpressibleByStringLiteral { + public init(stringLiteral value: String) { + try! self.init(value) + } +} + +extension TestableTargetReference: CustomStringConvertible { + public var reference: String { + switch location { + case .local: return name + case .project(let root), .package(let root): + return "\(root)/\(name)" + } + } + + public var description: String { + reference + } +} + +extension TestableTargetReference: JSONObjectConvertible { + + public init(jsonDictionary: JSONDictionary) throws { + if let project: String = jsonDictionary.json(atKeyPath: "project") { + let paths = project.split(separator: "/") + name = String(paths[1]) + location = .project(String(paths[0])) + } else if let project: String = jsonDictionary.json(atKeyPath: "package") { + let paths = project.split(separator: "/") + name = String(paths[1]) + location = .package(String(paths[0])) + } else { + name = try jsonDictionary.json(atKeyPath: "local") + location = .local + } + } +} + +extension TestableTargetReference: JSONEncodable { + public func toJSONValue() -> Any { + var dictionary: JSONDictionary = [:] + switch self.location { + case .package(let packageName): + dictionary["package"] = "\(packageName)/\(name)" + case .project(let projectName): + dictionary["project"] = "\(projectName)/\(name)" + case .local: + dictionary["local"] = name + } + return dictionary + } +} diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index fa008bb7b..e980b9948 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -136,9 +136,27 @@ public class SchemeGenerator { blueprintName: target.name ) } + + func getBuildableTestableReference(_ target: TestableTargetReference) throws -> XCScheme.BuildableReference { + switch target.location { + case .package(let packageName): + guard let package = self.project.getPackage(packageName), + case .local(let path) = package else { + throw SchemeGenerationError.missingPackage(packageName) + } + return XCScheme.BuildableReference( + referencedContainer: "container:\(path)", + blueprintIdentifier: target.name, + buildableName: target.name, + blueprintName: target.name + ) + default: + return try getBuildableReference(target.targetReference) + } + } func getBuildEntry(_ buildTarget: Scheme.BuildTarget) throws -> XCScheme.BuildAction.Entry { - let buildableReference = try getBuildableReference(buildTarget.target) + let buildableReference = try getBuildableTestableReference(buildTarget.target) return XCScheme.BuildAction.Entry(buildableReference: buildableReference, buildFor: buildTarget.buildTypes) } @@ -216,7 +234,7 @@ public class SchemeGenerator { } let coverageBuildableTargets = try scheme.test?.coverageTargets.map { - try getBuildableReference($0) + try getBuildableTestableReference($0) } ?? [] let testCommandLineArgs = scheme.test.map { XCScheme.CommandLineArguments($0.commandLineArguments) } @@ -375,6 +393,7 @@ public class SchemeGenerator { enum SchemeGenerationError: Error, CustomStringConvertible { case missingTarget(TargetReference, projectPath: String) + case missingPackage(String) case missingProject(String) case missingBuildTargets(String) @@ -386,6 +405,8 @@ enum SchemeGenerationError: Error, CustomStringConvertible { return "Unable to find project reference named \"\(project)\" in project.yml" case .missingBuildTargets(let name): return "Unable to find at least one build target in scheme \"\(name)\"" + case .missingPackage(let package): + return "Unable to find swift package named \"\(package)\" in project.yml" } } } @@ -436,14 +457,14 @@ extension Scheme { } private static func buildTargets(for target: Target, project: Project) -> [BuildTarget] { - let buildTarget = Scheme.BuildTarget(target: TargetReference.local(target.name)) + let buildTarget = Scheme.BuildTarget(target: TestableTargetReference.local(target.name)) switch target.type { case .watchApp, .watch2App: let hostTarget = project.targets .first { projectTarget in projectTarget.dependencies.contains { $0.reference == target.name } } - .map { BuildTarget(target: TargetReference.local($0.name)) } + .map { BuildTarget(target: TestableTargetReference.local($0.name)) } return hostTarget.map { [buildTarget, $0] } ?? [buildTarget] default: return [buildTarget] diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme index ed6efd9af..ff4048c2f 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -30,6 +30,26 @@ onlyGenerateCoverageForSpecifiedTargets = "NO" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + Date: Sun, 20 Mar 2022 14:28:41 +1100 Subject: [PATCH 25/55] Update CHANGELOG.md --- CHANGELOG.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca47f8e8..1ec079a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,18 @@ # Change Log ## Next Version + #### Added + - Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata +- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x - Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman -### Added - -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata -- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian - ## 2.26.0 ### Added From d7accac686cbb6b271d118a0b743784a1d6b1ca8 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Sun, 20 Mar 2022 14:30:49 +1100 Subject: [PATCH 26/55] Update to 2.27.0 --- CHANGELOG.md | 4 ++++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec079a8d..2d32e9bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.27.0 + #### Added - Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit @@ -13,6 +15,8 @@ - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x - Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman +[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.26.0...2.27.0) + ## 2.26.0 ### Added diff --git a/Makefile b/Makefile index aa515b3d4..c03ff6741 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.26.0 +VERSION = 2.27.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 6b036a520..f7ada854a 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.26.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.27.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index 8ba636bf8..fee309772 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.26.0") +let version = Version("2.27.0") let cli = XcodeGenCLI(version: version) cli.execute() From f6cdd090c22622c3e2254da167099e3980e9bd89 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Sun, 20 Mar 2022 14:44:14 +1100 Subject: [PATCH 27/55] use new TestableTargetReference in TargetScheme.coverageTargets --- Docs/ProjectSpec.md | 4 ++-- Sources/ProjectSpec/TargetScheme.swift | 9 ++++++--- Tests/XcodeGenKitTests/SchemeGeneratorTests.swift | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 70562385a..b9e5b2e67 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -653,7 +653,7 @@ This is a convenience used to automatically generate schemes for a target based - [x] **configVariants**: **[String]** - This generates a scheme for each entry, using configs that contain the name with debug and release variants. This is useful for having different environment schemes. - [ ] **testTargets**: **[[Test Target](#test-target)]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference) - a list of targets to gather code coverage. Each entry can either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **disableMainThreadChecker**: **Bool** - a boolean that indicates if this scheme should disable the Main Thread Checker. This defaults to false - [ ] **stopOnEveryMainThreadCheckerIssue**: **Bool** - a boolean that indicates if this scheme should stop at every Main Thread Checker issue. This defaults to false - [ ] **buildImplicitDependencies**: **Bool** - Flag to determine if Xcode should build implicit dependencies of this scheme. By default this is `true` if not set. @@ -828,7 +828,7 @@ A multiline script can be written using the various YAML multiline methods, for ### Test Action - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file - [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true. diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 136fd7965..9eb7f2792 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -11,7 +11,7 @@ public struct TargetScheme: Equatable { public var testTargets: [Scheme.Test.TestTarget] public var configVariants: [String] public var gatherCoverageData: Bool - public var coverageTargets: [TargetReference] + public var coverageTargets: [TestableTargetReference] public var storeKitConfiguration: String? public var language: String? public var region: String? @@ -27,7 +27,7 @@ public struct TargetScheme: Equatable { testTargets: [Scheme.Test.TestTarget] = [], configVariants: [String] = [], gatherCoverageData: Bool = gatherCoverageDataDefault, - coverageTargets: [TargetReference] = [], + coverageTargets: [TestableTargetReference] = [], storeKitConfiguration: String? = nil, language: String? = nil, region: String? = nil, @@ -77,7 +77,10 @@ extension TargetScheme: JSONObjectConvertible { if let targets = jsonDictionary["coverageTargets"] as? [Any] { coverageTargets = try targets.compactMap { target in if let string = target as? String { - return try TargetReference(string) + return try TestableTargetReference(string) + } else if let dictionary = target as? JSONDictionary, + let target: TestableTargetReference = try? .init(jsonDictionary: dictionary) { + return target } else { return nil } diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index 3257f3808..2d8202095 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -331,7 +331,7 @@ class SchemeGeneratorTests: XCTestCase { target.scheme = try TargetScheme( gatherCoverageData: true, coverageTargets: [ - TargetReference(framework.name), + TestableTargetReference(framework.name), ] ) From 8530da5d0027f1f2f85adce259802f564895c83d Mon Sep 17 00:00:00 2001 From: Maxim Bunkov Date: Tue, 22 Mar 2022 04:24:41 +0500 Subject: [PATCH 28/55] fix(carthage): shell login (#1179) * fix(carthage): shell login * tests(fixtures): update fixtures * tests(changelog): update changelog --- CHANGELOG.md | 1 + Sources/XcodeGenKit/PBXProjGenerator.swift | 2 +- .../Fixtures/TestProject/Project.xcodeproj/project.pbxproj | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d32e9bc4..0f749d9fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ - Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad - Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz - Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole +- Fix Monterey MacOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index c02f3a34d..990dd9e10 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -1130,7 +1130,7 @@ public class PBXProjGenerator { name: "Carthage", inputPaths: inputPaths, outputPaths: outputPaths, - shellPath: "/bin/sh", + shellPath: "/bin/sh -l", shellScript: "\(carthageExecutable) copy-frameworks\n" ) ) diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 2f440618d..f9df6bf94 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -2383,7 +2383,7 @@ "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; + shellPath = "/bin/sh -l"; shellScript = "carthage copy-frameworks\n"; }; 3D0637F4554EAD6FA48105BF /* MyScript */ = { @@ -2472,7 +2472,7 @@ "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; + shellPath = "/bin/sh -l"; shellScript = "carthage copy-frameworks\n"; }; BA454AAC926EDFCDA9226CBC /* MyScript */ = { @@ -2545,7 +2545,7 @@ "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; + shellPath = "/bin/sh -l"; shellScript = "carthage copy-frameworks\n"; }; /* End PBXShellScriptBuildPhase section */ From 5350e26cd5a2b08414877ebcf4a92f4095954e60 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Tue, 22 Mar 2022 10:25:44 +1100 Subject: [PATCH 29/55] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f749d9fb..37195e8eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Fixed + +- Fix Monterey macOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa + ## 2.27.0 #### Added @@ -40,7 +44,6 @@ - Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad - Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz - Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole -- Fix Monterey MacOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) From be0c3c39268ff403303450f3695a1eb611bbecb1 Mon Sep 17 00:00:00 2001 From: John Connolly Date: Thu, 24 Mar 2022 17:26:06 -0700 Subject: [PATCH 30/55] Added ability to use custom location for local Swift packages (#1175) * Added xcodePath functionality * Added xcodePath functionality * Renamed Xcode path to group * Updated change log and added fixture tests --- CHANGELOG.md | 3 ++ Docs/ProjectSpec.md | 4 +++ Sources/ProjectSpec/Project.swift | 2 +- Sources/ProjectSpec/SpecValidation.swift | 2 +- Sources/ProjectSpec/SwiftPackage.swift | 11 +++--- .../XcodeGenCLI/Commands/ProjectCommand.swift | 4 +-- Sources/XcodeGenKit/PBXProjGenerator.swift | 4 +-- Sources/XcodeGenKit/SchemeGenerator.swift | 2 +- Sources/XcodeGenKit/SourceGenerator.swift | 22 ++++++++---- .../SPM/SPM.xcodeproj/project.pbxproj | 19 +++++----- Tests/Fixtures/SPM/project.yml | 2 ++ Tests/ProjectSpecTests/ProjectSpecTests.swift | 2 +- Tests/ProjectSpecTests/SpecLoadingTests.swift | 10 +++--- .../ProjectGeneratorTests.swift | 35 +++++++++++++++++-- .../SchemeGeneratorTests.swift | 4 +-- 15 files changed, 90 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37195e8eb..71209a3fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next Version +#### Added +- Support for specifying custom group locations for SPM packages. [#1173](https://github.com/yonaskolb/XcodeGen/issues/1173) @John-Connolly + ### Fixed - Fix Monterey macOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index b9e5b2e67..936c2fa5f 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -993,6 +993,7 @@ Swift packages are defined at a project level, and then linked to individual tar ### Local Package - [x] **path**: **String** - the path to the package in local. The path must be directory with a `Package.swift`. +- [ ] **group** : **String**- Optional path that specifies the location where the package will live in your xcode project. ```yml packages: @@ -1004,6 +1005,9 @@ packages: from: 0.5.0 RxClient: path: ../RxClient + AppFeature: + path: ../Packages + group: Domains/AppFeature ``` ## Project Reference diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 972daa01c..f015d55f5 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -193,7 +193,7 @@ extension Project { packages.merge(localPackages.reduce(into: [String: SwiftPackage]()) { // Project name will be obtained by resolved abstractpath's lastComponent for dealing with some path case, like "../" let packageName = (basePath + Path($1).normalize()).lastComponent - $0[packageName] = .local(path: $1) + $0[packageName] = .local(path: $1, group: nil) } ) } diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index 01caca589..bf814ead4 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -54,7 +54,7 @@ extension Project { } for (name, package) in packages { - if case let .local(path) = package, !(basePath + Path(path).normalize()).exists { + if case let .local(path, _) = package, !(basePath + Path(path).normalize()).exists { errors.append(.invalidLocalPackage(name)) } } diff --git a/Sources/ProjectSpec/SwiftPackage.swift b/Sources/ProjectSpec/SwiftPackage.swift index 254882323..216a60617 100644 --- a/Sources/ProjectSpec/SwiftPackage.swift +++ b/Sources/ProjectSpec/SwiftPackage.swift @@ -10,7 +10,7 @@ public enum SwiftPackage: Equatable { static let githubPrefix = "https://github.com/" case remote(url: String, versionRequirement: VersionRequirement) - case local(path: String) + case local(path: String, group: String?) public var isLocal: Bool { if case .local = self { @@ -23,8 +23,10 @@ public enum SwiftPackage: Equatable { extension SwiftPackage: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { - if let path: String = jsonDictionary.json(atKeyPath: "path") { - self = .local(path: path) + if let path: String = jsonDictionary.json(atKeyPath: "path"), let customLocation: String = jsonDictionary.json(atKeyPath: "group") { + self = .local(path: path, group: customLocation) + } else if let path: String = jsonDictionary.json(atKeyPath: "path") { + self = .local(path: path, group: nil) } else { let versionRequirement: VersionRequirement = try VersionRequirement(jsonDictionary: jsonDictionary) try Self.validateVersion(versionRequirement: versionRequirement) @@ -90,8 +92,9 @@ extension SwiftPackage: JSONEncodable { dictionary["revision"] = revision } return dictionary - case .local(let path): + case let .local(path, group): dictionary["path"] = path + dictionary["group"] = group } return dictionary diff --git a/Sources/XcodeGenCLI/Commands/ProjectCommand.swift b/Sources/XcodeGenCLI/Commands/ProjectCommand.swift index c47967784..e20b82ea0 100644 --- a/Sources/XcodeGenCLI/Commands/ProjectCommand.swift +++ b/Sources/XcodeGenCLI/Commands/ProjectCommand.swift @@ -28,9 +28,9 @@ class ProjectCommand: Command { } func execute() throws { - + let projectSpecPath = (spec ?? "project.yml").absolute() - + if !projectSpecPath.exists { throw GenerationError.missingProjectSpec(projectSpecPath) } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 990dd9e10..20ffcfb0e 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -168,8 +168,8 @@ public class PBXProjGenerator { let packageReference = XCRemoteSwiftPackageReference(repositoryURL: url, versionRequirement: versionRequirement) packageReferences[name] = packageReference addObject(packageReference) - case let .local(path): - try sourceGenerator.createLocalPackage(path: Path(path)) + case let .local(path, group): + try sourceGenerator.createLocalPackage(path: Path(path), group: group.map { Path($0) }) } } diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index e980b9948..b96077243 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -141,7 +141,7 @@ public class SchemeGenerator { switch target.location { case .package(let packageName): guard let package = self.project.getPackage(packageName), - case .local(let path) = package else { + case let .local(path, _) = package else { throw SchemeGenerationError.missingPackage(packageName) } return XCScheme.BuildableReference( diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index c7667cf6e..fab9d3fe6 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -53,16 +53,22 @@ class SourceGenerator { return object } - func createLocalPackage(path: Path) throws { - - if localPackageGroup == nil { + func createLocalPackage(path: Path, group: Path?) throws { + var pbxGroup: PBXGroup? + + if let location = group { + let fullLocationPath = project.basePath + location + pbxGroup = getGroup(path: fullLocationPath, mergingChildren: [], createIntermediateGroups: true, hasCustomParent: false, isBaseGroup: true) + } + + if localPackageGroup == nil && group == nil { let groupName = project.options.localPackagesGroup ?? "Packages" localPackageGroup = addObject(PBXGroup(sourceTree: .sourceRoot, name: groupName)) rootGroups.insert(localPackageGroup!) } - + let absolutePath = project.basePath + path.normalize() - + // Get the local package's relative path from the project root let fileReferencePath = try? absolutePath.relativePath(from: projectDirectory ?? project.basePath).string @@ -74,7 +80,11 @@ class SourceGenerator { path: fileReferencePath ) ) - localPackageGroup!.children.append(fileReference) + if let pbxGroup = pbxGroup { + pbxGroup.children.append(fileReference) + } else { + localPackageGroup!.children.append(fileReference) + } } /// Collects an array complete of all `SourceFile` objects that make up the target based on the provided `TargetSource` definitions. diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj index 0f9810390..234e31cfe 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 23C6626698DE560017A89F2F /* XcodeGen in Frameworks */ = {isa = PBXBuildFile; productRef = 6F7DEA2D82649EDF903FBDBD /* XcodeGen */; }; 2DA7998902987953B119E4CE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F7EFEE613987D1E1258A60 /* AppDelegate.swift */; }; 3986ED6965842721C46C0452 /* SwiftRoaringDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */; }; 4CC663B42B270404EF5FD037 /* libStaticLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */; }; @@ -58,8 +59,8 @@ 61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLibrary.swift; sourceTree = ""; }; 7970A2253B14A9B27C307FAC /* SPMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPMTests.swift; sourceTree = ""; }; A9601593D0AD02931266A4E5 /* App.xctestplan */ = {isa = PBXFileReference; path = App.xctestplan; sourceTree = ""; }; - C1DE9A872F470EAA65B9B0B0 /* XcodeGen */ = {isa = PBXFileReference; lastKnownFileType = folder; name = XcodeGen; path = ../../..; sourceTree = SOURCE_ROOT; }; CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libStaticLibrary.a; sourceTree = BUILT_PRODUCTS_DIR; }; + ED284AB7C13DCC0A95DAA680 /* XcodeGen */ = {isa = PBXFileReference; lastKnownFileType = folder; name = XcodeGen; path = ../../..; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -70,6 +71,7 @@ CE46CBA5671B951B546C8673 /* Codability in Frameworks */, 3986ED6965842721C46C0452 /* SwiftRoaringDynamic in Frameworks */, 4CC663B42B270404EF5FD037 /* libStaticLibrary.a in Frameworks */, + 23C6626698DE560017A89F2F /* XcodeGen in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -83,6 +85,7 @@ 26F7EFEE613987D1E1258A60 /* AppDelegate.swift */, 4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */, 464ACF8D8F2D9F219BCFD3E7 /* Info.plist */, + ED284AB7C13DCC0A95DAA680 /* XcodeGen */, ); path = SPM; sourceTree = ""; @@ -98,7 +101,6 @@ 218F6C96DF9E182F526258CF = { isa = PBXGroup; children = ( - AD0F3623091EEA8D1EA3DFF8 /* Packages */, 17DD374CC81D710476AFF41C /* SPM */, CF3BD77AEAA56553289456BA /* SPMTests */, 1FA59BFD192FB5A68D5F587C /* StaticLibrary */, @@ -116,14 +118,6 @@ name = Products; sourceTree = ""; }; - AD0F3623091EEA8D1EA3DFF8 /* Packages */ = { - isa = PBXGroup; - children = ( - C1DE9A872F470EAA65B9B0B0 /* XcodeGen */, - ); - name = Packages; - sourceTree = SOURCE_ROOT; - }; CF3BD77AEAA56553289456BA /* SPMTests */ = { isa = PBXGroup; children = ( @@ -193,6 +187,7 @@ packageProductDependencies = ( 16E6FE01D5BD99F78D4A17E2 /* Codability */, DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */, + 6F7DEA2D82649EDF903FBDBD /* XcodeGen */, ); productName = App; productReference = 097F2DB5622B591E21BC3C73 /* App.app */; @@ -596,6 +591,10 @@ isa = XCSwiftPackageProductDependency; productName = XcodeGen; }; + 6F7DEA2D82649EDF903FBDBD /* XcodeGen */ = { + isa = XCSwiftPackageProductDependency; + productName = XcodeGen; + }; AF233B61592982A7F6431FC6 /* Codability */ = { isa = XCSwiftPackageProductDependency; package = 5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */; diff --git a/Tests/Fixtures/SPM/project.yml b/Tests/Fixtures/SPM/project.yml index 61d8e70bd..818f66ff9 100644 --- a/Tests/Fixtures/SPM/project.yml +++ b/Tests/Fixtures/SPM/project.yml @@ -8,6 +8,7 @@ packages: majorVersion: 1.0.4 XcodeGen: path: ../../.. #XcodeGen itself + group: SPM targets: App: type: application @@ -24,6 +25,7 @@ targets: product: SwiftRoaringDynamic embed: true - target: StaticLibrary + - package: XcodeGen Tests: type: bundle.unit-test platform: iOS diff --git a/Tests/ProjectSpecTests/ProjectSpecTests.swift b/Tests/ProjectSpecTests/ProjectSpecTests.swift index d0e74bcd8..cf8d50083 100644 --- a/Tests/ProjectSpecTests/ProjectSpecTests.swift +++ b/Tests/ProjectSpecTests/ProjectSpecTests.swift @@ -126,7 +126,7 @@ class ProjectSpecTests: XCTestCase { project.settings = invalidSettings project.configFiles = ["invalidConfig": "invalidConfigFile"] project.fileGroups = ["invalidFileGroup"] - project.packages = ["invalidLocalPackage": .local(path: "invalidLocalPackage")] + project.packages = ["invalidLocalPackage": .local(path: "invalidLocalPackage", group: nil)] project.settingGroups = ["settingGroup1": Settings( configSettings: ["invalidSettingGroupConfig": [:]], groups: ["invalidSettingGroupSettingGroup"] diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift index dbf361e46..5cc3afe50 100644 --- a/Tests/ProjectSpecTests/SpecLoadingTests.swift +++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift @@ -1227,9 +1227,10 @@ class SpecLoadingTests: XCTestCase { "package6": .remote(url: "package.git", versionRequirement: .range(from: "1.2.0", to: "1.2.5")), "package7": .remote(url: "package.git", versionRequirement: .exact("1.2.2")), "package8": .remote(url: "package.git", versionRequirement: .upToNextMajorVersion("4.0.0-beta.5")), - "package9": .local(path: "package/package"), + "package9": .local(path: "package/package", group: nil), "package10": .remote(url: "https://github.com/yonaskolb/XcodeGen", versionRequirement: .exact("1.2.2")), - "XcodeGen": .local(path: "../XcodeGen"), + "XcodeGen": .local(path: "../XcodeGen", group: nil), + "package11": .local(path: "../XcodeGen", group: "Packages/Feature"), ], options: .init(localPackagesGroup: "MyPackages")) let dictionary: [String: Any] = [ @@ -1248,6 +1249,7 @@ class SpecLoadingTests: XCTestCase { "package8": ["url": "package.git", "majorVersion": "4.0.0-beta.5"], "package9": ["path": "package/package"], "package10": ["github": "yonaskolb/XcodeGen", "exactVersion": "1.2.2"], + "package11": ["path": "../XcodeGen", "group": "Packages/Feature"], ], "localPackages": ["../XcodeGen"], ] @@ -1257,8 +1259,8 @@ class SpecLoadingTests: XCTestCase { $0.it("parses old local package format") { let project = Project(name: "spm", packages: [ - "XcodeGen": .local(path: "../XcodeGen"), - "Yams": .local(path: "Yams"), + "XcodeGen": .local(path: "../XcodeGen", group: nil), + "Yams": .local(path: "Yams", group: nil), ], options: .init(localPackagesGroup: "MyPackages")) let dictionary: [String: Any] = [ diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 8b3d71ec9..168bf4017 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -1271,7 +1271,7 @@ class ProjectGeneratorTests: XCTestCase { let project = Project(name: "test", targets: [app], packages: [ "XcodeGen": .remote(url: "http://github.com/yonaskolb/XcodeGen", versionRequirement: .branch("master")), "Codability": .remote(url: "http://github.com/yonaskolb/Codability", versionRequirement: .exact("1.0.0")), - "Yams": .local(path: "../Yams"), + "Yams": .local(path: "../Yams", group: nil), ], options: .init(localPackagesGroup: "MyPackages")) let pbxProject = try project.generatePbxProj(specValidate: false) @@ -1304,7 +1304,38 @@ class ProjectGeneratorTests: XCTestCase { ] ) - let project = Project(name: "test", targets: [app], packages: ["XcodeGen": .local(path: "../XcodeGen")]) + let project = Project(name: "test", targets: [app], packages: ["XcodeGen": .local(path: "../XcodeGen", group: nil)]) + + let pbxProject = try project.generatePbxProj(specValidate: false) + let nativeTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.name == app.name })) + let localPackageFile = try unwrap(pbxProject.fileReferences.first(where: { $0.path == "../XcodeGen" })) + try expect(localPackageFile.lastKnownFileType) == "folder" + + let frameworkPhases = nativeTarget.buildPhases.compactMap { $0 as? PBXFrameworksBuildPhase } + + guard let frameworkPhase = frameworkPhases.first else { + return XCTFail("frameworkPhases should have more than one") + } + + guard let file = frameworkPhase.files?.first else { + return XCTFail("frameworkPhase should have file") + } + + try expect(file.product?.productName) == "XcodeGen" + } + + + $0.it("generates local swift packages with custom xcode path") { + let app = Target( + name: "MyApp", + type: .application, + platform: .iOS, + dependencies: [ + Dependency(type: .package(product: nil), reference: "XcodeGen"), + ] + ) + + let project = Project(name: "test", targets: [app], packages: ["XcodeGen": .local(path: "../XcodeGen", group: "Packages/Feature")]) let pbxProject = try project.generatePbxProj(specValidate: false) let nativeTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.name == app.name })) diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index 2d8202095..c1d2f1591 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -404,7 +404,7 @@ class SchemeGeneratorTests: XCTestCase { name: "test", targets: [framework], schemes: [scheme], - packages: ["XcodeGen": .local(path: "../")], + packages: ["XcodeGen": .local(path: "../", group: nil)], projectReferences: [ ProjectReference(name: "TestProject", path: externalProject.string), ] @@ -493,7 +493,7 @@ class SchemeGeneratorTests: XCTestCase { let project = Project( name: "ios_test", targets: [app], - packages: ["XcodeGen": .local(path: "../")] + packages: ["XcodeGen": .local(path: "../", group: nil)] ) let xcodeProject = try project.generateXcodeProject() let xcscheme = try unwrap(xcodeProject.sharedData?.schemes.first) From 50aa8c51ccdfb2469e749a972fa1f7d7381038f5 Mon Sep 17 00:00:00 2001 From: Vladislav Lisyanskiy Date: Thu, 31 Mar 2022 09:15:58 +0400 Subject: [PATCH 31/55] Fixed segmentation fault crash (#1198) * Fixed glob segmentation fault * Renamed AtomicDictionary to ThreadSafeDictionary * Refactored ThreadSafeDictionary * ThreadSafeDictionary replaced with ThreadSafeContainer * Removed reader/writer * ThreadSafeContainer replaced with Atomic --- CHANGELOG.md | 1 + Sources/XcodeGenCore/Atomic.swift | 37 +++++++++++++++++---- Sources/XcodeGenCore/Glob.swift | 8 +++-- Tests/XcodeGenCoreTests/AtomicTests.swift | 39 +++++++++++++++++++++++ 4 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 Tests/XcodeGenCoreTests/AtomicTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 71209a3fa..153ea944b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed - Fix Monterey macOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa +- Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x ## 2.27.0 diff --git a/Sources/XcodeGenCore/Atomic.swift b/Sources/XcodeGenCore/Atomic.swift index c7911ca42..b3b1b2940 100644 --- a/Sources/XcodeGenCore/Atomic.swift +++ b/Sources/XcodeGenCore/Atomic.swift @@ -8,20 +8,45 @@ import Foundation @propertyWrapper -struct Atomic { - private let queue = DispatchQueue(label: "com.xcodegencore.atomic") +public final class Atomic { + private var value: Value - init(wrappedValue: Value) { + private let queue = DispatchQueue( + label: "com.xcodegencore.atomic.\(UUID().uuidString)", + qos: .utility, + attributes: .concurrent, + autoreleaseFrequency: .inherit, + target: .global() + ) + + public init(wrappedValue: Value) { self.value = wrappedValue } - var wrappedValue: Value { + public var wrappedValue: Value { get { - return queue.sync { value } + queue.sync { value } } set { - queue.sync { value = newValue } + queue.async(flags: .barrier) { [weak self] in + self?.value = newValue + } + } + } + + /// Allows us to get the actual `Atomic` instance with the $ + /// prefix. + public var projectedValue: Atomic { + return self + } + + /// Modifies the protected value using `closure`. + public func with( + _ closure: (inout Value) throws -> R + ) rethrows -> R { + try queue.sync(flags: .barrier) { + try closure(&value) } } } diff --git a/Sources/XcodeGenCore/Glob.swift b/Sources/XcodeGenCore/Glob.swift index e3025eab7..4cee0a801 100644 --- a/Sources/XcodeGenCore/Glob.swift +++ b/Sources/XcodeGenCore/Glob.swift @@ -198,13 +198,17 @@ public class Glob: Collection { var isDirectoryBool = ObjCBool(false) let isDirectory = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectoryBool) && isDirectoryBool.boolValue - isDirectoryCache[path] = isDirectory + $isDirectoryCache.with { isDirectoryCache in + isDirectoryCache[path] = isDirectory + } return isDirectory } private func clearCaches() { - isDirectoryCache.removeAll() + $isDirectoryCache.with { isDirectoryCache in + isDirectoryCache.removeAll() + } } private func paths(usingPattern pattern: String, includeFiles: Bool) -> [String] { diff --git a/Tests/XcodeGenCoreTests/AtomicTests.swift b/Tests/XcodeGenCoreTests/AtomicTests.swift new file mode 100644 index 000000000..470aeca35 --- /dev/null +++ b/Tests/XcodeGenCoreTests/AtomicTests.swift @@ -0,0 +1,39 @@ +// +// AtomicTests.swift +// +// +// Created by Vladislav Lisianskii on 27.03.2022. +// + +import XCTest +@testable import XcodeGenCore + +final class AtomicTests: XCTestCase { + + @Atomic private var atomicDictionary = [String: Int]() + + func testSimultaneousWriteOrder() { + let group = DispatchGroup() + + for index in (0..<100) { + group.enter() + DispatchQueue.global().async { + self.$atomicDictionary.with { atomicDictionary in + atomicDictionary["\(index)"] = index + } + group.leave() + } + } + + group.notify(queue: .main, execute: { + var expectedValue = [String: Int]() + for index in (0..<100) { + expectedValue["\(index)"] = index + } + XCTAssertEqual( + self.atomicDictionary, + expectedValue + ) + }) + } +} From 17e7b0327870c1df4d479eb09c351e5d91bf66bb Mon Sep 17 00:00:00 2001 From: Alvar Hansen Date: Thu, 31 Mar 2022 08:16:31 +0300 Subject: [PATCH 32/55] Run target source pattern matching in parallel (#1197) As this transform closure does not access anything outside of its closure and does not mutate any singletons, then it seems to be safe to run this mapping in parallel. --- CHANGELOG.md | 4 ++++ Sources/XcodeGenKit/SourceGenerator.swift | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 153ea944b..84003cb84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ - Fix Monterey macOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x +### Changed + +- Run target source pattern matching in parallel [#1197](https://github.com/yonaskolb/XcodeGen/pull/1197) @alvarhansen + ## 2.27.0 #### Added diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index fab9d3fe6..e788ef09d 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -359,7 +359,7 @@ class SourceGenerator { let rootSourcePath = project.basePath + targetSource.path return Set( - patterns.map { pattern in + patterns.parallelMap { pattern in guard !pattern.isEmpty else { return [] } return Glob(pattern: "\(rootSourcePath)/\(pattern)") .map { Path($0) } From 4fbdc9da35c433f54971bd875e5c405b7b223f14 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Thu, 31 Mar 2022 16:22:09 +1100 Subject: [PATCH 33/55] Update to 2.28.0 --- Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c03ff6741..467033559 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.27.0 +VERSION = 2.28.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index f7ada854a..8966c4c0e 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.27.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.28.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index fee309772..f64962f9e 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.27.0") +let version = Version("2.28.0") let cli = XcodeGenCLI(version: version) cli.execute() From 322c5658f3427e25bdca673759e9938ec179d761 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Thu, 31 Mar 2022 16:24:02 +1100 Subject: [PATCH 34/55] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84003cb84..b23923836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## Next Version +## 2.28.0 + #### Added + - Support for specifying custom group locations for SPM packages. [#1173](https://github.com/yonaskolb/XcodeGen/issues/1173) @John-Connolly ### Fixed @@ -14,6 +17,8 @@ - Run target source pattern matching in parallel [#1197](https://github.com/yonaskolb/XcodeGen/pull/1197) @alvarhansen +[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.27.0...2.28.0) + ## 2.27.0 #### Added From 958ae1b744c6ecf96a04f7ca6ddea9a5e730defa Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Thu, 31 Mar 2022 16:41:05 +1100 Subject: [PATCH 35/55] simplify changelog PR links Github now makes these links in more contexts --- CHANGELOG.md | 850 +++++++++++++++++++++++++-------------------------- 1 file changed, 425 insertions(+), 425 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b23923836..6e1de9098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,16 @@ #### Added -- Support for specifying custom group locations for SPM packages. [#1173](https://github.com/yonaskolb/XcodeGen/issues/1173) @John-Connolly +- Support for specifying custom group locations for SPM packages. #1173 @John-Connolly ### Fixed -- Fix Monterey macOS shell version, shell login flag for environments [#1167](https://github.com/yonaskolb/XcodeGen/issues/1167) @bimawa -- Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x +- Fix Monterey macOS shell version, shell login flag for environments #1167 @bimawa +- Fixed crash caused by a simultaneous write during a glob processing #1177 @tr1ckyf0x ### Changed -- Run target source pattern matching in parallel [#1197](https://github.com/yonaskolb/XcodeGen/pull/1197) @alvarhansen +- Run target source pattern matching in parallel #1197 @alvarhansen [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.27.0...2.28.0) @@ -23,14 +23,14 @@ #### Added -- Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata -- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian +- Support test target for local Swift Package #1074 @freddi-kit +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. #1189 @gabriellanata +- Fixed issue where .gyb files could not be added to source file list #1191 @hakkurishian ### Fixed -- Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x -- Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman +- Fixed crash caused by a simultaneous write during a glob processing #1177 @tr1ckyf0x +- Skip generating empty compile sources build phases for watch apps #1185 @evandcoleman [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.26.0...2.27.0) @@ -38,43 +38,43 @@ ### Added -- Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack +- Added the option to specify a `location` in a test target #1150 @KrisRJack ### Changed -- Speed up source inclusion checking for big projects [#1122](https://github.com/yonaskolb/XcodeGen/pull/1122) @PaulTaykalo +- Speed up source inclusion checking for big projects #1122 @PaulTaykalo [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.25.0...2.26.0) ## 2.25.0 ### Added -- Allow specifying a `copy` setting for each dependency. [#1038](https://github.com/yonaskolb/XcodeGen/pull/1039) @JakubBednar +- Allow specifying a `copy` setting for each dependency. #1038 @JakubBednar ### Fixed -- Fix broken codesign option for bundle dependency [#1104](https://github.com/yonaskolb/XcodeGen/pull/1104) @kateinoigakukun -- Ensure fileTypes are mapped to JSON value [#1112](https://github.com/yonaskolb/XcodeGen/pull/1112) @namolnad -- Fix platform filter for package dependecies [#1123](https://github.com/yonaskolb/XcodeGen/pull/1123) @raptorxcz -- Fix Xcode 13 build [#1130](https://github.com/yonaskolb/XcodeGen/issues/1127) @raptorxcz @mthole +- Fix broken codesign option for bundle dependency #1104 @kateinoigakukun +- Ensure fileTypes are mapped to JSON value #1112 @namolnad +- Fix platform filter for package dependecies #1123 @raptorxcz +- Fix Xcode 13 build #1130 @raptorxcz @mthole [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) ### Changed -- Update XcodeProj to 8.2.0 [#1125](https://github.com/yonaskolb/XcodeGen/pull/1125) @nnsnodnb +- Update XcodeProj to 8.2.0 #1125 @nnsnodnb ## 2.24.0 ### Added -- Added support for DocC Catalogs [#1091](https://github.com/yonaskolb/XcodeGen/pull/1091) @brevansio -- Added support for "driver-extension" and "system-extension" product types [#1092](https://github.com/yonaskolb/XcodeGen/issues/1092) @vgorloff -- Add support for conditionally linking dependencies for specific platforms [#1087](https://github.com/yonaskolb/XcodeGen/pull/1087) @daltonclaybrook -- Add ability to specify UI testing screenshot behavior in test schemes [#942](https://github.com/yonaskolb/XcodeGen/pull/942) @daltonclaybrook +- Added support for DocC Catalogs #1091 @brevansio +- Added support for "driver-extension" and "system-extension" product types #1092 @vgorloff +- Add support for conditionally linking dependencies for specific platforms #1087 @daltonclaybrook +- Add ability to specify UI testing screenshot behavior in test schemes #942 @daltonclaybrook ### Changed -- **Breaking**: Rename the `platform` field on `Dependency` to `platformFilter` [#1087](https://github.com/yonaskolb/XcodeGen/pull/1087) @daltonclaybrook +- **Breaking**: Rename the `platform` field on `Dependency` to `platformFilter` #1087 @daltonclaybrook [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.23.1...2.24.0) @@ -82,450 +82,450 @@ ### Changed - Reverted "Change FRAMEWORK_SEARCH_PATH for xcframeworks (#1015)", introduced in 2.20.0. XCFrameworks need to be - referenced directly in the project for Xcode's build system to extract the appropriate frameworks [#1081](https://github.com/yonaskolb/XcodeGen/pull/1081) @elliottwilliams + referenced directly in the project for Xcode's build system to extract the appropriate frameworks #1081 @elliottwilliams [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.23.0...2.23.1) ## 2.23.0 #### Added -- Added ability to set custom platform for dependency [#934](https://github.com/yonaskolb/XcodeGen/pull/934) @raptorxcz +- Added ability to set custom platform for dependency #934 @raptorxcz #### Fixed -- Added `()` to config variant trimming charater set to fix scheme config variant lookups for some configs like `Debug (Development)` that broke in 2.22.0 [#1078](https://github.com/yonaskolb/XcodeGen/pull/1078) @DavidWoohyunLee -- Fixed Linux builds on Swift 5.4 [#1083](https://github.com/yonaskolb/XcodeGen/pull/1083) @yonaskolb +- Added `()` to config variant trimming charater set to fix scheme config variant lookups for some configs like `Debug (Development)` that broke in 2.22.0 #1078 @DavidWoohyunLee +- Fixed Linux builds on Swift 5.4 #1083 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.22.0...2.23.0) ## 2.22.0 #### Added -- Support `runPostActionsOnFailure` for running build post scripts on failing build [#1075](https://github.com/yonaskolb/XcodeGen/pull/1075) @freddi-kit +- Support `runPostActionsOnFailure` for running build post scripts on failing build #1075 @freddi-kit #### Changed -- Xcode no longer alerts to project changes after regeneration, due to internal workspace not regenerating if identical [#1072](https://github.com/yonaskolb/XcodeGen/pull/1072) @yonaskolb +- Xcode no longer alerts to project changes after regeneration, due to internal workspace not regenerating if identical #1072 @yonaskolb #### Fixed -- Fixed no such module `DOT` error when package is used as a dependency [#1067](https://github.com/yonaskolb/XcodeGen/pull/1067) @yanamura -- Fixed scheme config variant lookups for some configs like `ProdDebug` and `Prod-Debug` that broke in 2.21.0 [#1070](https://github.com/yonaskolb/XcodeGen/pull/1070) @yonaskolb +- Fixed no such module `DOT` error when package is used as a dependency #1067 @yanamura +- Fixed scheme config variant lookups for some configs like `ProdDebug` and `Prod-Debug` that broke in 2.21.0 #1070 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.21.0...2.22.0) ## 2.21.0 #### Added -- Support weak link for Swift Package Dependency [#1064](https://github.com/yonaskolb/XcodeGen/pull/1064) @freddi-kit +- Support weak link for Swift Package Dependency #1064 @freddi-kit #### Changed -- Carthage frameworks are no longer embedded for "order-only" target dependencies. This avoid redundant embeds in situations where a target's sources _import_ a Carthage framework but do not have a binary dependency on it (like a test target which runs in a host app). [#1041](https://github.com/yonaskolb/XcodeGen/pull/1041) @elliottwilliams +- Carthage frameworks are no longer embedded for "order-only" target dependencies. This avoid redundant embeds in situations where a target's sources _import_ a Carthage framework but do not have a binary dependency on it (like a test target which runs in a host app). #1041 @elliottwilliams #### Fixed -- The `Core` target is renamed to avoid collisions with other packages. [#1057](https://github.com/yonaskolb/XcodeGen/pull/1057) @elliottwilliams -- Lookup scheme config variants by whole words, fixing incorrect assignment in names that contain subtrings of each other (eg PreProd and Prod) [#976](https://github.com/yonaskolb/XcodeGen/pull/976) @stefanomondino +- The `Core` target is renamed to avoid collisions with other packages. #1057 @elliottwilliams +- Lookup scheme config variants by whole words, fixing incorrect assignment in names that contain subtrings of each other (eg PreProd and Prod) #976 @stefanomondino [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.20.0...2.21.0) ## 2.20.0 #### Added -- Allow specifying a `github` name like `JohnSundell/Ink` instead of a full `url` for Swift Packages [#1029](https://github.com/yonaskolb/XcodeGen/pull/1029) @yonaskolb +- Allow specifying a `github` name like `JohnSundell/Ink` instead of a full `url` for Swift Packages #1029 @yonaskolb - Added explicity `LastUpgradeCheck` and `LastUpgradeVersion` override support so it's possible to override these properties without using the `project.xcodeVersion`. [1013](https://github.com/yonaskolb/XcodeGen/pull/1013) @Andre113 -- Added `macroExpansion` for `run` in `schemes` [#1036](https://github.com/yonaskolb/XcodeGen/pull/1036) @freddi-kit -- Added `askForAppToLaunch` for `profile` in `schemes` [#1035](https://github.com/yonaskolb/XcodeGen/pull/1035) @freddi-kit -- Added support for selectedTests in schemes `Test` configuration. [#913](https://github.com/yonaskolb/XcodeGen/pull/913) @ooodin +- Added `macroExpansion` for `run` in `schemes` #1036 @freddi-kit +- Added `askForAppToLaunch` for `profile` in `schemes` #1035 @freddi-kit +- Added support for selectedTests in schemes `Test` configuration. #913 @ooodin #### Fixed -- Fixed regression on `.storekit` configuration files' default build phase. [#1026](https://github.com/yonaskolb/XcodeGen/pull/1026) @jcolicchio -- Fixed framework search paths when using `.xcframework`s. [#1015](https://github.com/yonaskolb/XcodeGen/pull/1015) @FranzBusch -- Fixed bug where schemes without a build target would crash instead of displaying an error [#1040](https://github.com/yonaskolb/XcodeGen/pull/1040) @dalemyers -- Fixed files with names ending in **Info.plist** (such as **GoogleServices-Info.plist**) from being omitted from the Copy Resources build phase. Now, only the resolved info plist file for each specific target is omitted. [#1027](https://github.com/yonaskolb/XcodeGen/pull/1027) @liamnichols +- Fixed regression on `.storekit` configuration files' default build phase. #1026 @jcolicchio +- Fixed framework search paths when using `.xcframework`s. #1015 @FranzBusch +- Fixed bug where schemes without a build target would crash instead of displaying an error #1040 @dalemyers +- Fixed files with names ending in **Info.plist** (such as **GoogleServices-Info.plist**) from being omitted from the Copy Resources build phase. Now, only the resolved info plist file for each specific target is omitted. #1027 @liamnichols #### Internal -- Build universal binaries for release. XcodeGen now runs natively on Apple Silicon. [#1024](https://github.com/yonaskolb/XcodeGen/pull/1024) @thii +- Build universal binaries for release. XcodeGen now runs natively on Apple Silicon. #1024 @thii [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.19.0...2.20.0) ## 2.19.0 #### Added -- Added support for building and running on Linux platforms. Tested for compatibility with Swift 5.3+ and Ubuntu 18.04. [#988](https://github.com/yonaskolb/XcodeGen/pull/988) @elliottwilliams -- Added `useBaseInternationalization` to Project Spec Options to opt out of Base Internationalization. [#961](https://github.com/yonaskolb/XcodeGen/pull/961) @liamnichols -- Added `storeKitConfiguration` to allow specifying StoreKit Configuration in Scheme and TargetScheme, supporting either xcodeproj or xcworkspace via `schemePathPrefix` option. [#964](https://github.com/yonaskolb/XcodeGen/pull/964) @jcolicchio -- Added more detailed error message with method arguments. [#990](https://github.com/yonaskolb/XcodeGen/pull/990) @bannzai -- Added `basedOnDependencyAnalysis` to Project Spec Build Script to be able to choose not to skip the script. [#992](https://github.com/yonaskolb/XcodeGen/pull/992) @myihsan -- Added `BuildRule.runOncePerArchitecture` to allow running build rules once per architecture. [#950](https://github.com/yonaskolb/XcodeGen/pull/950) @sascha -- Added discovered dependency file for a build script [#1012](https://github.com/yonaskolb/XcodeGen/pull/1012) @polac24 @fggeraissate +- Added support for building and running on Linux platforms. Tested for compatibility with Swift 5.3+ and Ubuntu 18.04. #988 @elliottwilliams +- Added `useBaseInternationalization` to Project Spec Options to opt out of Base Internationalization. #961 @liamnichols +- Added `storeKitConfiguration` to allow specifying StoreKit Configuration in Scheme and TargetScheme, supporting either xcodeproj or xcworkspace via `schemePathPrefix` option. #964 @jcolicchio +- Added more detailed error message with method arguments. #990 @bannzai +- Added `basedOnDependencyAnalysis` to Project Spec Build Script to be able to choose not to skip the script. #992 @myihsan +- Added `BuildRule.runOncePerArchitecture` to allow running build rules once per architecture. #950 @sascha +- Added discovered dependency file for a build script #1012 @polac24 @fggeraissate #### Changed -- **Breaking**: Info.plists with custom prefixes are no longer added to the Copy Bundle Resources build phase [#945](https://github.com/yonaskolb/XcodeGen/pull/945) @anivaros -- **Breaking**: `workingDirectory` of included legacy targets is now made relative to including project [#981](https://github.com/yonaskolb/XcodeGen/pull/981) @jcolicchio -- **Breaking**: Make `simulateLocation` respect `schemePathPrefix` option. [#973](https://github.com/yonaskolb/XcodeGen/pull/973) @jcolicchio +- **Breaking**: Info.plists with custom prefixes are no longer added to the Copy Bundle Resources build phase #945 @anivaros +- **Breaking**: `workingDirectory` of included legacy targets is now made relative to including project #981 @jcolicchio +- **Breaking**: Make `simulateLocation` respect `schemePathPrefix` option. #973 @jcolicchio #### Fixed -- Fixed error message output for `minimumXcodeGenVersion`. [#967](https://github.com/yonaskolb/XcodeGen/pull/967) @joshwalker -- Remove force-unwrapping causing crash for `LegacyTarget`s [#982](https://github.com/yonaskolb/XcodeGen/pull/982) @jcolicchio -- Fixed a race condition in an internal JSON decoder, which would occasionally fail with an error like `Parsing project spec failed: Error Domain=Unspecified error Code=0`. [#995](https://github.com/yonaskolb/XcodeGen/pull/995) @elliottwilliams -- Fixed issue where frameworks with `MACH_O_TYPE: staticlib` were being incorrectly embedded. [#1003](https://github.com/yonaskolb/XcodeGen/pull/1003) @mrabiciu +- Fixed error message output for `minimumXcodeGenVersion`. #967 @joshwalker +- Remove force-unwrapping causing crash for `LegacyTarget`s #982 @jcolicchio +- Fixed a race condition in an internal JSON decoder, which would occasionally fail with an error like `Parsing project spec failed: Error Domain=Unspecified error Code=0`. #995 @elliottwilliams +- Fixed issue where frameworks with `MACH_O_TYPE: staticlib` were being incorrectly embedded. #1003 @mrabiciu #### Internal -- Updated to Yams 4.0.0 [#984](https://github.com/yonaskolb/XcodeGen/pull/984) @swiftty +- Updated to Yams 4.0.0 #984 @swiftty [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.18.0...2.19.0) ## 2.18.0 #### Added -- Add `Scheme.Test.TestTarget.skipped` to allow skipping of an entire test target. [#916](https://github.com/yonaskolb/XcodeGen/pull/916) @codeman9 -- Added ability to set custom LLDBInit scripts for launch and test schemes [#929](https://github.com/yonaskolb/XcodeGen/pull/929) @polac24 -- Adds App Clip support. [#909](https://github.com/yonaskolb/XcodeGen/pull/909) @brentleyjones @dflems -- Application extension schemes now default to `launchAutomaticallySubstyle = 2` and the correct debugger and launcher identifiers [#932](https://github.com/yonaskolb/XcodeGen/pull/932) @brentleyjones -- Updated SettingsPresets to use new defaults from Xcode 12. [#953](https://github.com/yonaskolb/XcodeGen/pull/953) @liamnichols -- Enable Base Internationalization by default as per Xcode 12 behavior. [#954](https://github.com/yonaskolb/XcodeGen/issues/954) @liamnichols +- Add `Scheme.Test.TestTarget.skipped` to allow skipping of an entire test target. #916 @codeman9 +- Added ability to set custom LLDBInit scripts for launch and test schemes #929 @polac24 +- Adds App Clip support. #909 @brentleyjones @dflems +- Application extension schemes now default to `launchAutomaticallySubstyle = 2` and the correct debugger and launcher identifiers #932 @brentleyjones +- Updated SettingsPresets to use new defaults from Xcode 12. #953 @liamnichols +- Enable Base Internationalization by default as per Xcode 12 behavior. #954 @liamnichols #### Changed -- Change default project version to Xcode 12 [#960](https://github.com/yonaskolb/XcodeGen/pull/960) @yonaskolb +- Change default project version to Xcode 12 #960 @yonaskolb #### Internal -- Updates CI to run on Xcode 12. [#936](https://github.com/yonaskolb/XcodeGen/pull/936) [#960](https://github.com/yonaskolb/XcodeGen/pull/960) @dflems @yonaskolb +- Updates CI to run on Xcode 12. #936 @dflems @yonaskolb #### Fixed -- Select the first runnable build target, if present. [#957](https://github.com/yonaskolb/XcodeGen/pull/957) @codeman9 -- Allow SDK dependencies to be embedded. [#922](https://github.com/yonaskolb/XcodeGen/pull/922) @k-thorat -- Allow creating intermediary groups outside of the project directory. [#892](https://github.com/yonaskolb/XcodeGen/pull/892) @segiddins -- Fix appex's Runpath Search Paths under macOS target. [#952](https://github.com/yonaskolb/XcodeGen/pull/952) @rinsuki -- `onlyCopyFilesOnInstall` is extended for the Embed App Extensions build phase. [#948](https://github.com/yonaskolb/XcodeGen/pull/948) @RomanPodymov +- Select the first runnable build target, if present. #957 @codeman9 +- Allow SDK dependencies to be embedded. #922 @k-thorat +- Allow creating intermediary groups outside of the project directory. #892 @segiddins +- Fix appex's Runpath Search Paths under macOS target. #952 @rinsuki +- `onlyCopyFilesOnInstall` is extended for the Embed App Extensions build phase. #948 @RomanPodymov [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.17.0...2.18.0) ## 2.17.0 #### Added -- Added `options.fileTypes` which lets you set cross project defaults for certain file extensions [#914](https://github.com/yonaskolb/XcodeGen/pull/914) @yonaskolb -- Added `onlyCopyFilesOnInstall` option to targets for the Embed Files build phase. [#912](https://github.com/yonaskolb/XcodeGen/pull/912) @jsorge +- Added `options.fileTypes` which lets you set cross project defaults for certain file extensions #914 @yonaskolb +- Added `onlyCopyFilesOnInstall` option to targets for the Embed Files build phase. #912 @jsorge #### Fixed -- Treat all directories with known UTI as file wrapper. [#896](https://github.com/yonaskolb/XcodeGen/pull/896) @KhaosT -- Generated schemes for application extensions now contain `wasCreatedForAppExtension = YES`. [#898](https://github.com/yonaskolb/XcodeGen/issues/898) @muizidn -- Allow package dependencies to use `link: false` [#920](https://github.com/yonaskolb/XcodeGen/pull/920) @k-thorat -- Fixed issue computing relative paths. [#915](https://github.com/yonaskolb/XcodeGen/pull/915) @andrewreach +- Treat all directories with known UTI as file wrapper. #896 @KhaosT +- Generated schemes for application extensions now contain `wasCreatedForAppExtension = YES`. #898 @muizidn +- Allow package dependencies to use `link: false` #920 @k-thorat +- Fixed issue computing relative paths. #915 @andrewreach #### Internal -- Updated to XcodeProj 7.13.0 [#908](https://github.com/yonaskolb/XcodeGen/pull/908) @brentleyjones +- Updated to XcodeProj 7.13.0 #908 @brentleyjones [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.16.0...2.17.0) ## 2.16.0 #### Added -- Improve speed of metadata parsing and dependency resolution. [#803](https://github.com/yonaskolb/XcodeGen/pull/803) @michaeleisel -- Improve support for iOS sticker packs and add support for `launchAutomaticallySubstyle` to run schemes. [#824](https://github.com/yonaskolb/XcodeGen/pull/824) @scelis -- Add --project-root option to generate command. [#828](https://github.com/yonaskolb/XcodeGen/pull/828) @ileitch -- Add an ability to set an order of groups with `options.groupOrdering` [#613](https://github.com/yonaskolb/XcodeGen/pull/613) @Beniamiiin -- Add the ability to output a dependency graph in graphviz format [#852](https://github.com/yonaskolb/XcodeGen/pull/852) @jeffctown -- Adds uncluttering the project manifest dumped to YAML from empty values [#858](https://github.com/yonaskolb/XcodeGen/pull/858) @paciej00 -- Added ability to name the executable target when declaring schemes. [#869](https://github.com/yonaskolb/XcodeGen/pull/869) @elland -- Added ability to set executable to Ask to Launch. [#871](https://github.com/yonaskolb/XcodeGen/pull/871) @pinda +- Improve speed of metadata parsing and dependency resolution. #803 @michaeleisel +- Improve support for iOS sticker packs and add support for `launchAutomaticallySubstyle` to run schemes. #824 @scelis +- Add --project-root option to generate command. #828 @ileitch +- Add an ability to set an order of groups with `options.groupOrdering` #613 @Beniamiiin +- Add the ability to output a dependency graph in graphviz format #852 @jeffctown +- Adds uncluttering the project manifest dumped to YAML from empty values #858 @paciej00 +- Added ability to name the executable target when declaring schemes. #869 @elland +- Added ability to set executable to Ask to Launch. #871 @pinda #### Fixed -- Fixed issue when linking and embeding static frameworks: they should be linked and NOT embed. [#820](https://github.com/yonaskolb/XcodeGen/pull/820) @acecilia -- Fixed issue when generating projects for paths with a dot in the folder for swift sources. [#826](https://github.com/yonaskolb/XcodeGen/pull/826) @asifmohd -- Prefix static library target filenames with 'lib' to match Xcode. [#831](https://github.com/yonaskolb/XcodeGen/pull/831), [#842](https://github.com/yonaskolb/XcodeGen/pull/842) @ileitch -- Fixed duplicate addition of carthage static frameworks. [#829](https://github.com/yonaskolb/XcodeGen/pull/829) @funzin -- Fix handling of SWIFT_INSTALL_OBJC_HEADER when its value is YES/NO. [#827](https://github.com/yonaskolb/XcodeGen/pull/827) @ileitch -- Set `preActions` and `postActions` on the `build` action of a TargetScheme instead of the other actions. [#823](https://github.com/yonaskolb/XcodeGen/pull/823) @brentleyjones -- Prevent test targets from being set as a scheme's launch action [#835](https://github.com/yonaskolb/XcodeGen/pull/835) @brentleyjones -- Implicitly include bundles in the Copy Bundle Resources build phase. [#838](https://github.com/yonaskolb/XcodeGen/pull/838) @skirchmeier -- Fixed dumping a project manifest which contains an array of project references [#840](https://github.com/yonaskolb/XcodeGen/pull/840) @paciej00 -- Generate correct PBXTargetDependency for external targets. [#843](https://github.com/yonaskolb/XcodeGen/pull/843) @ileitch -- Fix linking of multiple products from the same Swift Package [#830](https://github.com/yonaskolb/XcodeGen/pull/830) @toshi0383 -- Don't deduplicate files in `include` with different path but same name. [#849](https://github.com/yonaskolb/XcodeGen/pull/849) @akkyie -- Don't link transitive static carthage libraries. [#853](https://github.com/yonaskolb/XcodeGen/pull/853) @akkyie -- Optimize simplifying paths for faster project generation. [#857](https://github.com/yonaskolb/XcodeGen/pull/857) @akkyie -- Fixed issue where wrapper folders may not include correctly in the generated project. [#862](https://github.com/yonaskolb/XcodeGen/pull/862) @KhaosT -- Compile `xcmappingmodel` files instead of copying bundle resources. [#834](https://github.com/yonaskolb/XcodeGen/pull/834) @jcolicchio -- Fixed issue where `Complie Sources` build phase is generated for resource bundles even when they have no files to compile [#878](https://github.com/yonaskolb/XcodeGen/pull/878) @nkukushkin +- Fixed issue when linking and embeding static frameworks: they should be linked and NOT embed. #820 @acecilia +- Fixed issue when generating projects for paths with a dot in the folder for swift sources. #826 @asifmohd +- Prefix static library target filenames with 'lib' to match Xcode. #831 @ileitch +- Fixed duplicate addition of carthage static frameworks. #829 @funzin +- Fix handling of SWIFT_INSTALL_OBJC_HEADER when its value is YES/NO. #827 @ileitch +- Set `preActions` and `postActions` on the `build` action of a TargetScheme instead of the other actions. #823 @brentleyjones +- Prevent test targets from being set as a scheme's launch action #835 @brentleyjones +- Implicitly include bundles in the Copy Bundle Resources build phase. #838 @skirchmeier +- Fixed dumping a project manifest which contains an array of project references #840 @paciej00 +- Generate correct PBXTargetDependency for external targets. #843 @ileitch +- Fix linking of multiple products from the same Swift Package #830 @toshi0383 +- Don't deduplicate files in `include` with different path but same name. #849 @akkyie +- Don't link transitive static carthage libraries. #853 @akkyie +- Optimize simplifying paths for faster project generation. #857 @akkyie +- Fixed issue where wrapper folders may not include correctly in the generated project. #862 @KhaosT +- Compile `xcmappingmodel` files instead of copying bundle resources. #834 @jcolicchio +- Fixed issue where `Complie Sources` build phase is generated for resource bundles even when they have no files to compile #878 @nkukushkin [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.15.1...2.16.0) ## 2.15.1 #### Fixed -- Fixed issue which caused watch app schemes to be generated incorrectly, preventing these apps from launching. [#798](https://github.com/yonaskolb/XcodeGen/pull/798) @daltonclaybrook -- Added build presets for the target type `framework.static`. [#819](https://github.com/yonaskolb/XcodeGen/pull/819) @acecilia -- Fixed XcodeProj resolution and updated to 7.10.0 [#822](https://github.com/yonaskolb/XcodeGen/pull/822) @soffes +- Fixed issue which caused watch app schemes to be generated incorrectly, preventing these apps from launching. #798 @daltonclaybrook +- Added build presets for the target type `framework.static`. #819 @acecilia +- Fixed XcodeProj resolution and updated to 7.10.0 #822 @soffes [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.15.0...2.15.1) ## 2.15.0 #### Added -- Add support for local Swift Packages in `packages` using `path`. [#808](https://github.com/yonaskolb/XcodeGen/pull/808) @freddi-kit -- Add `buildImplicitDependencies` as an option on `TargetScheme`. [#810](https://github.com/yonaskolb/XcodeGen/pull/810) @evandcoleman +- Add support for local Swift Packages in `packages` using `path`. #808 @freddi-kit +- Add `buildImplicitDependencies` as an option on `TargetScheme`. #810 @evandcoleman #### Fixed -- Fixed resolving path to local Swift Packages [#796](https://github.com/yonaskolb/XcodeGen/pull/796) @freddi-kit -- Added ability to stop on every main thread checker issue on Run schemes and TargetSchemes [#799](https://github.com/yonaskolb/XcodeGen/pull/799) @ionutivan -- Avoid copying ObjC interface header when SWIFT_INSTALL_OBJC_HEADER=false. [#805](https://github.com/yonaskolb/XcodeGen/pull/805) @kateinoigakukun +- Fixed resolving path to local Swift Packages #796 @freddi-kit +- Added ability to stop on every main thread checker issue on Run schemes and TargetSchemes #799 @ionutivan +- Avoid copying ObjC interface header when SWIFT_INSTALL_OBJC_HEADER=false. #805 @kateinoigakukun [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.14.0...2.15.0) ## 2.14.0 #### Added -- Add ability to embed and code sign Swift package dependencies with dynamic products. [#788](https://github.com/yonaskolb/XcodeGen/pull/788) @alexruperez +- Add ability to embed and code sign Swift package dependencies with dynamic products. #788 @alexruperez #### Fixed -- Revert "Add Base to known regions even if one doesn't exist" [#791](https://github.com/yonaskolb/XcodeGen/pull/792) @bryansum -- Set `defaultConfigurationName` for every target which is defined in a project. [#787](https://github.com/yonaskolb/XcodeGen/pull/787) @ken0nek -- Set `TEST_TARGET_NAME` only when a project has UITest bundle. [#792](https://github.com/yonaskolb/XcodeGen/pull/792) @ken0nek -- Set xcodeproj path in project.xcworkspace/contents.xcworkspacedata [#793](https://github.com/yonaskolb/XcodeGen/pull/793) @ken0nek +- Revert "Add Base to known regions even if one doesn't exist" #791 @bryansum +- Set `defaultConfigurationName` for every target which is defined in a project. #787 @ken0nek +- Set `TEST_TARGET_NAME` only when a project has UITest bundle. #792 @ken0nek +- Set xcodeproj path in project.xcworkspace/contents.xcworkspacedata #793 @ken0nek [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.13.1...2.14.0) ## 2.13.1 #### Fixed -- Validate scheme test action and test coverage target references before generating. [#775](https://github.com/yonaskolb/XcodeGen/pull/775) @liamnichols -- Fixed parsing prerelease identifiers in Swift package versions [#779](https://github.com/yonaskolb/XcodeGen/pull/779) @yonaskolb -- Fixed using legacy targets as dependencies [#778](https://github.com/yonaskolb/XcodeGen/pull/778) @yonaskolb +- Validate scheme test action and test coverage target references before generating. #775 @liamnichols +- Fixed parsing prerelease identifiers in Swift package versions #779 @yonaskolb +- Fixed using legacy targets as dependencies #778 @yonaskolb #### Internal -- Updated to XcodeProj 7.8.0 [#777](https://github.com/yonaskolb/XcodeGen/pull/777) @yonaskolb -- Use https://github.com/mxcl/Version [#779](https://github.com/yonaskolb/XcodeGen/pull/779) @yonaskolb +- Updated to XcodeProj 7.8.0 #777 @yonaskolb +- Use https://github.com/mxcl/Version #779 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.13.0...2.13.1) ## 2.13.0 #### Added -- Support External Target References via subprojects. [#701](https://github.com/yonaskolb/XcodeGen/pull/701) @evandcoleman +- Support External Target References via subprojects. #701 @evandcoleman #### Fixed -- Fixed compilation as library by locking down XcodeProj version [#767](https://github.com/yonaskolb/XcodeGen/pull/767) @yonaskolb -- Stabilized sorting of groups with duplicate names/paths. [#671](https://github.com/yonaskolb/XcodeGen/pull/671) @ChristopherRogers -- Moved `Copy Bundle Resources` to after `Link with Libraries` build phase [#768](https://github.com/yonaskolb/XcodeGen/pull/768) @yonaskolb +- Fixed compilation as library by locking down XcodeProj version #767 @yonaskolb +- Stabilized sorting of groups with duplicate names/paths. #671 @ChristopherRogers +- Moved `Copy Bundle Resources` to after `Link with Libraries` build phase #768 @yonaskolb #### Internal -- Updated to XcodeProj 7.7.0 [#767](https://github.com/yonaskolb/XcodeGen/pull/767) @yonaskolb +- Updated to XcodeProj 7.7.0 #767 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.12.0...2.13.0) ## 2.12.0 #### Added -- Added pre and post command options. Useful for running `pod install` in combination with `--use-cache` [#759](https://github.com/yonaskolb/XcodeGen/pull/759) @yonaskolb -- Support for language and region settings on a target basis [#728](https://github.com/yonaskolb/XcodeGen/pull/728) @FranzBusch -- Added option to generate only Info.plist files with `--only-plists` [#739](https://github.com/yonaskolb/XcodeGen/pull/739) @namolnad -- Added the option to specify a `simulateLocation` in a scheme [#722](https://github.com/yonaskolb/XcodeGen/issues/722) @basvankuijck -- Support for On Demand Resources tags [#753](https://github.com/yonaskolb/XcodeGen/pull/753) @sipao +- Added pre and post command options. Useful for running `pod install` in combination with `--use-cache` #759 @yonaskolb +- Support for language and region settings on a target basis #728 @FranzBusch +- Added option to generate only Info.plist files with `--only-plists` #739 @namolnad +- Added the option to specify a `simulateLocation` in a scheme #722 @basvankuijck +- Support for On Demand Resources tags #753 @sipao #### Fixed -- Fixed resolving a relative path for `projectReference.path` [#740](https://github.com/yonaskolb/XcodeGen/pull/740) @kateinoigakukun -- Don't add framework dependency's directory to `FRAMEWORK_SEARCH_PATHS` if it is implicit [#744](https://github.com/yonaskolb/XcodeGen/pull/744) @ikesyo @yutailang0119 -- Fixed resolving relative path passed to `XcodeProj` [#751](https://github.com/yonaskolb/XcodeGen/pull/751) @PycKamil -- Prefer configurations named "Debug" or "Release" for default scheme build configurations [#752](https://github.com/yonaskolb/XcodeGen/pull/752) @john-flanagan -- Added an extra check for package versions. [#755](https://github.com/yonaskolb/XcodeGen/pull/755) @basvankuijck +- Fixed resolving a relative path for `projectReference.path` #740 @kateinoigakukun +- Don't add framework dependency's directory to `FRAMEWORK_SEARCH_PATHS` if it is implicit #744 @ikesyo @yutailang0119 +- Fixed resolving relative path passed to `XcodeProj` #751 @PycKamil +- Prefer configurations named "Debug" or "Release" for default scheme build configurations #752 @john-flanagan +- Added an extra check for package versions. #755 @basvankuijck #### Internal -- Update to SwiftCLI 6.0 and use the new property wrappers [#749](https://github.com/yonaskolb/XcodeGen/pull/749) @yonaskolb +- Update to SwiftCLI 6.0 and use the new property wrappers #749 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.11.0...2.12.0) ## 2.11.0 #### Added -- Add Carthage static framework dependencies support. [#688](https://github.com/yonaskolb/XcodeGen/pull/688) @giginet -- Added `xcodegen dump` command [#710](https://github.com/yonaskolb/XcodeGen/pull/710) @yonaskolb -- Added `--no-env` option to disable environment variables expansion [#704](https://github.com/yonaskolb/XcodeGen/pull/704) @rcari -- Added custom group support for target sources [#621](https://github.com/yonaskolb/XcodeGen/pull/621) @sroebert @rcari -- Added new dependency type, `bundle`. This allows targets to copy bundles from other projects [#616](https://github.com/yonaskolb/XcodeGen/pull/616) @bsmith11 +- Add Carthage static framework dependencies support. #688 @giginet +- Added `xcodegen dump` command #710 @yonaskolb +- Added `--no-env` option to disable environment variables expansion #704 @rcari +- Added custom group support for target sources #621 @sroebert @rcari +- Added new dependency type, `bundle`. This allows targets to copy bundles from other projects #616 @bsmith11 #### Fixed -- Improved variable expansion runtime [#704](https://github.com/yonaskolb/XcodeGen/pull/704) @rcari -- Fixed missing headers for static framework targets [#705](https://github.com/yonaskolb/XcodeGen/pull/705) @wag-miles -- Using more file types from XcodeProj for PBXFileReferences resulting in less project diffs [#715](https://github.com/yonaskolb/XcodeGen/pull/715) @yonaskolb -- Fixed localized `*.intentdefinition` not being added to build source phases [#720](https://github.com/yonaskolb/XcodeGen/pull/720) @giginet -- Fixed `selectedLauncherIdentifier` not being set `Xcode.IDEFoundation.Launcher.PosixSpawn` when `debugEnabled: false` is defined in test action [#725](https://github.com/yonaskolb/XcodeGen/pull/725) @ken0nek -- Fixed unnecessary dependencies related to SwiftPM [#726](https://github.com/yonaskolb/XcodeGen/pull/726) @tid-kijyun +- Improved variable expansion runtime #704 @rcari +- Fixed missing headers for static framework targets #705 @wag-miles +- Using more file types from XcodeProj for PBXFileReferences resulting in less project diffs #715 @yonaskolb +- Fixed localized `*.intentdefinition` not being added to build source phases #720 @giginet +- Fixed `selectedLauncherIdentifier` not being set `Xcode.IDEFoundation.Launcher.PosixSpawn` when `debugEnabled: false` is defined in test action #725 @ken0nek +- Fixed unnecessary dependencies related to SwiftPM #726 @tid-kijyun #### Changed -- Deprecated `$old_form` variables in favor of `${new_form}` variables [#704](https://github.com/yonaskolb/XcodeGen/pull/704) @rcari -- Updated XcodeProj to 7.4.0 [#709](https://github.com/yonaskolb/XcodeGen/pull/709) [#715](https://github.com/yonaskolb/XcodeGen/pull/715) @yonaskolb -- Updated to Swift 5.1 [#714](https://github.com/yonaskolb/XcodeGen/pull/714) @yonaskolb +- Deprecated `$old_form` variables in favor of `${new_form}` variables #704 @rcari +- Updated XcodeProj to 7.4.0 #709 @yonaskolb +- Updated to Swift 5.1 #714 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.10.1...2.11.0) ## 2.10.1 #### Fixed -- Add Base to knownRegions even if one doesn't exist [#694](https://github.com/yonaskolb/XcodeGen/pull/694) @bryansum -- Fixed missing `onlyGenerateCoverageForSpecifiedTargets` issue [#700](https://github.com/yonaskolb/XcodeGen/pull/700) @kateinoigakukun -- Fixed regression on dependencies `link` flag [#703](https://github.com/yonaskolb/XcodeGen/pull/703) @rcari +- Add Base to knownRegions even if one doesn't exist #694 @bryansum +- Fixed missing `onlyGenerateCoverageForSpecifiedTargets` issue #700 @kateinoigakukun +- Fixed regression on dependencies `link` flag #703 @rcari [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.10.0...2.10.1) ## 2.10.0 #### Added -- Support Target Reference to another project. [#655](https://github.com/yonaskolb/XcodeGen/pull/655) @kateinoigakukun -- Added `coverageTargets` for test target. This enables to gather code coverage for specific targets. [#656](https://github.com/yonaskolb/XcodeGen/pull/656) @kateinoigakukun +- Support Target Reference to another project. #655 @kateinoigakukun +- Added `coverageTargets` for test target. This enables to gather code coverage for specific targets. #656 @kateinoigakukun #### Fixed -- Add base localisation by default even if no base localised files were found. Fixes warning in Xcode 11 [#685](https://github.com/yonaskolb/XcodeGen/pull/685) @yonaskolb -- Don't generate CFBundleExecutable in default generated Info.plist for `bundle` target types [#689](https://github.com/yonaskolb/XcodeGen/pull/689) @FranzBusch -- Fixed resolving relative paths with custom project destination [#681](https://github.com/yonaskolb/XcodeGen/pull/681) @giginet -- Fixed resolving relative paths for Info.plist [#683](https://github.com/yonaskolb/XcodeGen/pull/683) @giginet -- Fixed macOS unit test target TEST_HOST [#696](https://github.com/yonaskolb/XcodeGen/pull/696) @mjarvis +- Add base localisation by default even if no base localised files were found. Fixes warning in Xcode 11 #685 @yonaskolb +- Don't generate CFBundleExecutable in default generated Info.plist for `bundle` target types #689 @FranzBusch +- Fixed resolving relative paths with custom project destination #681 @giginet +- Fixed resolving relative paths for Info.plist #683 @giginet +- Fixed macOS unit test target TEST_HOST #696 @mjarvis #### Internal -- Restructure targets [#698](https://github.com/yonaskolb/XcodeGen/pull/698) @yonaskolb +- Restructure targets #698 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.9.0...2.10.0) ## 2.9.0 #### Added -- Added Scheme Templates [#672](https://github.com/yonaskolb/XcodeGen/pull/672) @bclymer +- Added Scheme Templates #672 @bclymer #### Fixed -- Fixed macOS unit test setting preset [#665](https://github.com/yonaskolb/XcodeGen/pull/665) @yonaskolb -- Add `rcproject` files to sources build phase instead of resources [#669](https://github.com/yonaskolb/XcodeGen/pull/669) @Qusic -- Prefer default configuration names for generated schemes [#673](https://github.com/yonaskolb/XcodeGen/pull/673) @giginet -- Fixed some resource files being placed to "Recovered References" group [#679](https://github.com/yonaskolb/XcodeGen/pull/679) @nivanchikov +- Fixed macOS unit test setting preset #665 @yonaskolb +- Add `rcproject` files to sources build phase instead of resources #669 @Qusic +- Prefer default configuration names for generated schemes #673 @giginet +- Fixed some resource files being placed to "Recovered References" group #679 @nivanchikov #### Internal -- Updated to SwiftCLI 5.3.2 [#667](https://github.com/yonaskolb/XcodeGen/pull/667) @giginet -- Fixed tests in case-sensitive file system [#670](https://github.com/yonaskolb/XcodeGen/pull/670) @Qusic +- Updated to SwiftCLI 5.3.2 #667 @giginet +- Fixed tests in case-sensitive file system #670 @Qusic [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.8.0...2.9.0) ## 2.8.0 #### Added -- Added support for Swift Package dependencies [#624](https://github.com/yonaskolb/XcodeGen/pull/624) @yonaskolb -- Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. [#637](https://github.com/yonaskolb/XcodeGen/pull/637) @bclymer -- Support `dylib` SDK. [#650](https://github.com/yonaskolb/XcodeGen/pull/650) @kateinoigakukun -- Added `language` and `region` options for `run` and `test` scheme [#654](https://github.com/yonaskolb/XcodeGen/pull/654) @kateinoigakukun -- Added `debugEnabled` option for `run` and `test` scheme [#657](https://github.com/yonaskolb/XcodeGen/pull/657) @kateinoigakukun +- Added support for Swift Package dependencies #624 @yonaskolb +- Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. #637 @bclymer +- Support `dylib` SDK. #650 @kateinoigakukun +- Added `language` and `region` options for `run` and `test` scheme #654 @kateinoigakukun +- Added `debugEnabled` option for `run` and `test` scheme #657 @kateinoigakukun #### Fixed -- Expand template variable in Array of Any [#651](https://github.com/yonaskolb/XcodeGen/pull/651) @kateinoigakukun -- Significantly improve performance when running with a large number files. [#658](https://github.com/yonaskolb/XcodeGen/pull/658) @kateinoigakukun -- Removed some more diffs between the generated .pbxproj and when Xcode resaves it [#663](https://github.com/yonaskolb/XcodeGen/pull/663) @yonaskolb +- Expand template variable in Array of Any #651 @kateinoigakukun +- Significantly improve performance when running with a large number files. #658 @kateinoigakukun +- Removed some more diffs between the generated .pbxproj and when Xcode resaves it #663 @yonaskolb #### Internal -- Removed needless `Array` initialization. [#661](https://github.com/yonaskolb/XcodeGen/pull/661) @RomanPodymov -- Updated to XcodeProj 7.1.0 [#624](https://github.com/yonaskolb/XcodeGen/pull/624) @yonaskolb +- Removed needless `Array` initialization. #661 @RomanPodymov +- Updated to XcodeProj 7.1.0 #624 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.7.0...2.8.0) ## 2.7.0 #### Added -- Added Bash 4 style recursive globbing (`**/*`) in target sources `excludes` [#636](https://github.com/yonaskolb/XcodeGen/pull/636) @bclymer -- Added ability to disable main thread checker in Schemes [#601](https://github.com/yonaskolb/XcodeGen/pull/601) @wag-miles +- Added Bash 4 style recursive globbing (`**/*`) in target sources `excludes` #636 @bclymer +- Added ability to disable main thread checker in Schemes #601 @wag-miles #### Fixed -- Fixed included specs that were referenced multiple times from duplicating content [#599](https://github.com/yonaskolb/XcodeGen/pull/599) @haritowa -- Fixed `.orig` files being added to the project [#627](https://github.com/yonaskolb/XcodeGen/pull/627) @keith +- Fixed included specs that were referenced multiple times from duplicating content #599 @haritowa +- Fixed `.orig` files being added to the project #627 @keith #### Changed -- Allow linking of dependencies into static libraries when `link` is set to true [#635](https://github.com/yonaskolb/XcodeGen/pull/635) @kateinoigakukun +- Allow linking of dependencies into static libraries when `link` is set to true #635 @kateinoigakukun [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.6.0...2.7.0) ## 2.6.0 #### Added -- Added ability to skip tests [#582](https://github.com/yonaskolb/XcodeGen/pull/582) @kadarandras -- Added ability to set `attributes` on build files [#583](https://github.com/yonaskolb/XcodeGen/pull/583) @min -- Allow using environment variables in the form of `${SOME_VARIABLE}`. This might be a **breaking** change when a target template attribute is also defined as an environment variable [#594](https://github.com/yonaskolb/XcodeGen/pull/594) @tomquist -- Added support for `watchapp2-container` and `framework.static` product types [#604](https://github.com/yonaskolb/XcodeGen/pull/604) @yonaskolb +- Added ability to skip tests #582 @kadarandras +- Added ability to set `attributes` on build files #583 @min +- Allow using environment variables in the form of `${SOME_VARIABLE}`. This might be a **breaking** change when a target template attribute is also defined as an environment variable #594 @tomquist +- Added support for `watchapp2-container` and `framework.static` product types #604 @yonaskolb #### Fixed -- Fixed `.pch` files being bundled as resources [#597](https://github.com/yonaskolb/XcodeGen/pull/597) @thii -- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#571](https://github.com/yonaskolb/XcodeGen/pull/571) @KhaosT +- Fixed `.pch` files being bundled as resources #597 @thii +- Fixed an issue that prevents watchOS Intents Extension from running correctly. #571 @KhaosT #### Changed -- Updated the default `compatibilityVersion` project setting from `Xcode 9.3` to `Xcode 10.0` [#581](https://github.com/yonaskolb/XcodeGen/pull/581) @acecilia -- Updated to XcodeProj 7.0.0. Note that the length of generated UUIDs has changed [#604](https://github.com/yonaskolb/XcodeGen/pull/604) @yonaskolb +- Updated the default `compatibilityVersion` project setting from `Xcode 9.3` to `Xcode 10.0` #581 @acecilia +- Updated to XcodeProj 7.0.0. Note that the length of generated UUIDs has changed #604 @yonaskolb #### Internal -- Added ability to encode ProjectSpec [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey +- Added ability to encode ProjectSpec #545 @ryohey [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.5.0...2.6.0) ## 2.5.0 #### Added -- Added support for `app-extension.intents-service` target type [#536](https://github.com/yonaskolb/XcodeGen/pull/536) @yonaskolb -- Added support for custom `root` in `sdk` dependency [#562](https://github.com/yonaskolb/XcodeGen/pull/562) @raptorxcz +- Added support for `app-extension.intents-service` target type #536 @yonaskolb +- Added support for custom `root` in `sdk` dependency #562 @raptorxcz #### Changed -- Updated to xcodeproj 6.7.0 including its performance improvements [#536](https://github.com/yonaskolb/XcodeGen/pull/536) @yonaskolb -- Updated default generated settings for Xcode 10.2 [#555](https://github.com/yonaskolb/XcodeGen/pull/555) @yonaskolb -- Changed order of file generation so that plists are now generated before the project, so they will be included in the projects files [#544](https://github.com/yonaskolb/XcodeGen/issues/544) @tomquist +- Updated to xcodeproj 6.7.0 including its performance improvements #536 @yonaskolb +- Updated default generated settings for Xcode 10.2 #555 @yonaskolb +- Changed order of file generation so that plists are now generated before the project, so they will be included in the projects files #544 @tomquist - Updated Yams to 2.0.0 @yonaskolb #### Fixed -- Fixed groups from sources outside a project spec's directory from being flattened. [#550](https://github.com/yonaskolb/XcodeGen/pull/550) @sroebert -- Fixed `optional` file sources not being added to the project [#557](https://github.com/yonaskolb/XcodeGen/pull/557) @yonaskolb -- Fixed Carthage dependencies being incorrectly embedded in WatchKit app bundles instead of a WatchKit app extension [#558](https://github.com/yonaskolb/XcodeGen/pull/558) @KhaosT +- Fixed groups from sources outside a project spec's directory from being flattened. #550 @sroebert +- Fixed `optional` file sources not being added to the project #557 @yonaskolb +- Fixed Carthage dependencies being incorrectly embedded in WatchKit app bundles instead of a WatchKit app extension #558 @KhaosT [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.4.0...2.5.0) ## 2.4.0 #### Fixed: -- Fixed installation when building in Swift 5 [#549](https://github.com/yonaskolb/XcodeGen/pull/549) @yonaskolb +- Fixed installation when building in Swift 5 #549 @yonaskolb #### Changed -- Updated to Swift 5 and dropped Swift 4.2 [#549](https://github.com/yonaskolb/XcodeGen/pull/549) @yonaskolb +- Updated to Swift 5 and dropped Swift 4.2 #549 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.3.0...2.4.0) ## 2.3.0 #### Added -- Added ability to automatically find all the frameworks for Carthage dependencies via the global `options.findCarthageFrameworks` or dependency specfic `dependency.findFrameworks`. See the [Carthage](Docs/Usage.md#carthage) usage docs for more info [#506](https://github.com/yonaskolb/XcodeGen/pull/506) [#543](https://github.com/yonaskolb/XcodeGen/pull/543) @rpassis @yonaskolb -- Added support for nested target templates [#534](https://github.com/yonaskolb/XcodeGen/pull/534) @tomquist -- Added ability to define `templateAttributes` within a target to be able to parameterize templates. [#533](https://github.com/yonaskolb/XcodeGen/pull/533) @tomquist -- Added ability to set `link` to false in framework dependencies [#532](https://github.com/yonaskolb/XcodeGen/pull/532) @dimatosaurus +- Added ability to automatically find all the frameworks for Carthage dependencies via the global `options.findCarthageFrameworks` or dependency specfic `dependency.findFrameworks`. See the [Carthage](Docs/Usage.md#carthage) usage docs for more info #506 @rpassis @yonaskolb +- Added support for nested target templates #534 @tomquist +- Added ability to define `templateAttributes` within a target to be able to parameterize templates. #533 @tomquist +- Added ability to set `link` to false in framework dependencies #532 @dimatosaurus - Added `missingConfigFiles` to `options.disabledValidations` to optionally skip checking for the existence of config files. -- Added ability to define a per-platform `deploymentTarget` for Multi-Platform targets. [#510](https://github.com/yonaskolb/XcodeGen/pull/510) @ainopara +- Added ability to define a per-platform `deploymentTarget` for Multi-Platform targets. #510 @ainopara #### Changed -- **DEPRECATION**: Placeholders `$target_name` and `$platform` have been deprecated in favour of `${target_name}` and `${platform}`. Support for the old placeholders will be removed in a future version [#533](https://github.com/yonaskolb/XcodeGen/pull/533) @tomquist +- **DEPRECATION**: Placeholders `$target_name` and `$platform` have been deprecated in favour of `${target_name}` and `${platform}`. Support for the old placeholders will be removed in a future version #533 @tomquist #### Fixed -- Sources outside a project spec's directory will be correctly referenced as relative paths in the project file. [#524](https://github.com/yonaskolb/XcodeGen/pull/524) -- Fixed error when `optional` directory source is missing [#527](https://github.com/yonaskolb/XcodeGen/pull/527) @yonaskolb -- Fixed excludes within included spec [#535](https://github.com/yonaskolb/XcodeGen/pull/535) @yonaskolb -- Fixed paths in target templates within included files not being relative [#537](https://github.com/yonaskolb/XcodeGen/pull/537) @yonaskolb -- Fix multi-platform target templates [#541](https://github.com/yonaskolb/XcodeGen/pull/541) @yonaskolb -- Fixed sources in an included target not being relative when the sources are mix of string and dictionaries [#542](https://github.com/yonaskolb/XcodeGen/pull/542) @yonaskolb +- Sources outside a project spec's directory will be correctly referenced as relative paths in the project file. #524 +- Fixed error when `optional` directory source is missing #527 @yonaskolb +- Fixed excludes within included spec #535 @yonaskolb +- Fixed paths in target templates within included files not being relative #537 @yonaskolb +- Fix multi-platform target templates #541 @yonaskolb +- Fixed sources in an included target not being relative when the sources are mix of string and dictionaries #542 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.2.0...2.3.0) ## 2.2.0 #### Added -- Added ability to generate empty directories via `options.generateEmptyDirectories` [#480](https://github.com/yonaskolb/XcodeGen/pull/480) @Beniamiiin -- Added support for the `instrumentsPackage` product type [#482](https://github.com/yonaskolb/XcodeGen/pull/482) @ksulliva -- Added support for `inputFileLists` and `outputFileLists` within project build scripts [#500](https://github.com/yonaskolb/XcodeGen/pull/500) @lukewakeford -- Added support for a `$target_name` replacement string within target templates [#504](https://github.com/yonaskolb/XcodeGen/pull/504) @yonaskolb -- Added `createIntermediateGroups` to individual Target Sources which overrides the top level option [#505](https://github.com/yonaskolb/XcodeGen/pull/505) @yonaskolb +- Added ability to generate empty directories via `options.generateEmptyDirectories` #480 @Beniamiiin +- Added support for the `instrumentsPackage` product type #482 @ksulliva +- Added support for `inputFileLists` and `outputFileLists` within project build scripts #500 @lukewakeford +- Added support for a `$target_name` replacement string within target templates #504 @yonaskolb +- Added `createIntermediateGroups` to individual Target Sources which overrides the top level option #505 @yonaskolb #### Changed -- **BREAKING**: All the paths within `include` files are now relative to that file and not the root spec. This can be disabled with a `relativePaths: false` on the include. See the [documentation](https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md#include) for more details [#489](https://github.com/yonaskolb/XcodeGen/pull/489) @ellneal -- Updated the Xcode compatibility version from 3.2 to 9.3 [#497](https://github.com/yonaskolb/XcodeGen/pull/497) @yonaskolb -- Exact matches to config names in build settings won't partial apply to other configs [#503](https://github.com/yonaskolb/XcodeGen/pull/503) @yonaskolb +- **BREAKING**: All the paths within `include` files are now relative to that file and not the root spec. This can be disabled with a `relativePaths: false` on the include. See the [documentation](https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md#include) for more details #489 @ellneal +- Updated the Xcode compatibility version from 3.2 to 9.3 #497 @yonaskolb +- Exact matches to config names in build settings won't partial apply to other configs #503 @yonaskolb - UUIDs in the project are standard and don't contain any type prefixes anymore #### Fixed -- Fixed `--project` argument not taking effect [#487](https://github.com/yonaskolb/XcodeGen/pull/487) @monowerker -- Fixed Sticker Packs from generating an empty Source file phase which caused in error in the new build system [#492](https://github.com/yonaskolb/XcodeGen/pull/492) @rpassis -- Fixed generated schemes for tool targets not setting the executable [#496](https://github.com/yonaskolb/XcodeGen/pull/496) @yonaskolb +- Fixed `--project` argument not taking effect #487 @monowerker +- Fixed Sticker Packs from generating an empty Source file phase which caused in error in the new build system #492 @rpassis +- Fixed generated schemes for tool targets not setting the executable #496 @yonaskolb - Fixed resolving Carthage dependencies for iOS app with watchOS target. [465](https://github.com/yonaskolb/XcodeGen/pull/465) @raptorxcz [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.1.0...2.2.0) @@ -533,48 +533,48 @@ ## 2.1.0 #### Added -- Added an experiment new caching feature. Pass `--use-cache` to opt in. This will read and write from a cache file to prevent unnecessarily generating the project. Give it a try as it may become the default in a future release [#412](https://github.com/yonaskolb/XcodeGen/pull/412) @yonaskolb +- Added an experiment new caching feature. Pass `--use-cache` to opt in. This will read and write from a cache file to prevent unnecessarily generating the project. Give it a try as it may become the default in a future release #412 @yonaskolb #### Changed - Changed spelling of build phases to **preBuildPhase** and **postBuildPhase**. The older names are deprecated but still work [402](https://github.com/yonaskolb/XcodeGen/pull/402) @brentleyjones -- Moved generation to a specific subcommand `xcodegen generate`. Simple `xcodegen` will continue to work for now [#437](https://github.com/yonaskolb/XcodeGen/pull/437) @yonaskolb -- If `INFOPLIST_FILE` has been set on a target, then an `info` path won't ovewrite it [#443](https://github.com/yonaskolb/XcodeGen/pull/443) @feischl97 +- Moved generation to a specific subcommand `xcodegen generate`. Simple `xcodegen` will continue to work for now #437 @yonaskolb +- If `INFOPLIST_FILE` has been set on a target, then an `info` path won't ovewrite it #443 @feischl97 #### Fixed -- Fixed XPC Service package type in generated `Info.plist` [#435](https://github.com/yonaskolb/XcodeGen/pull/435) @alvarhansen +- Fixed XPC Service package type in generated `Info.plist` #435 @alvarhansen - Fixed phase ordering for modulemap and static libary header Copy File phases. [402](https://github.com/yonaskolb/XcodeGen/pull/402) @brentleyjones -- Fixed intermittent errors when running multiple `xcodegen`s concurrently [#450](https://github.com/yonaskolb/XcodeGen/pull/450) @bryansum -- Fixed `--project` argument not working [#437](https://github.com/yonaskolb/XcodeGen/pull/437) @yonaskolb -- Fixed unit tests not hooking up to host applications properly by default. They now generate a `TEST_HOST` and a `TestTargetID` [#452](https://github.com/yonaskolb/XcodeGen/pull/452) @yonaskolb -- Fixed static libraries not including external frameworks in their search paths [#454](https://github.com/yonaskolb/XcodeGen/pull/454) @brentleyjones -- Add `.intentdefinition` files to sources build phase instead of resources [#442](https://github.com/yonaskolb/XcodeGen/pull/442) @yonaskolb -- Add `mlmodel` files to sources build phase instead of resources [#457](https://github.com/yonaskolb/XcodeGen/pull/457) @dwb357 +- Fixed intermittent errors when running multiple `xcodegen`s concurrently #450 @bryansum +- Fixed `--project` argument not working #437 @yonaskolb +- Fixed unit tests not hooking up to host applications properly by default. They now generate a `TEST_HOST` and a `TestTargetID` #452 @yonaskolb +- Fixed static libraries not including external frameworks in their search paths #454 @brentleyjones +- Add `.intentdefinition` files to sources build phase instead of resources #442 @yonaskolb +- Add `mlmodel` files to sources build phase instead of resources #457 @dwb357 [Commits](https://github.com/yonaskolb/XcodeGen/compare/2.0.0...2.1.0) ## 2.0.0 #### Added -- Added `weak` linking setting for dependencies [#411](https://github.com/yonaskolb/XcodeGen/pull/411) @alvarhansen -- Added `info` to targets for generating an `Info.plist` [#415](https://github.com/yonaskolb/XcodeGen/pull/415) @yonaskolb -- Added `entitlements` to targets for generating an `.entitlement` file [#415](https://github.com/yonaskolb/XcodeGen/pull/415) @yonaskolb -- Added `sdk` dependency type for linking system frameworks and libs [#430](https://github.com/yonaskolb/XcodeGen/pull/430) @yonaskolb -- Added `parallelizable` and `randomExecutionOrder` to `Scheme` test targets in an expanded form [#434](https://github.com/yonaskolb/XcodeGen/pull/434) @yonaskolb -- Validate incorrect config setting definitions [#431](https://github.com/yonaskolb/XcodeGen/pull/431) @yonaskolb -- Automatically set project `SDKROOT` if there is only a single platform within the project [#433](https://github.com/yonaskolb/XcodeGen/pull/433) @yonaskolb +- Added `weak` linking setting for dependencies #411 @alvarhansen +- Added `info` to targets for generating an `Info.plist` #415 @yonaskolb +- Added `entitlements` to targets for generating an `.entitlement` file #415 @yonaskolb +- Added `sdk` dependency type for linking system frameworks and libs #430 @yonaskolb +- Added `parallelizable` and `randomExecutionOrder` to `Scheme` test targets in an expanded form #434 @yonaskolb +- Validate incorrect config setting definitions #431 @yonaskolb +- Automatically set project `SDKROOT` if there is only a single platform within the project #433 @yonaskolb #### Changed -- Performance improvements for large projects [#388](https://github.com/yonaskolb/XcodeGen/pull/388) [#417](https://github.com/yonaskolb/XcodeGen/pull/417) [#416](https://github.com/yonaskolb/XcodeGen/pull/416) @yonaskolb @kastiglione -- Upgraded to xcodeproj 6 [#388](https://github.com/yonaskolb/XcodeGen/pull/388) @yonaskolb -- Upgraded to Swift 4.2 [#388](https://github.com/yonaskolb/XcodeGen/pull/388) @yonaskolb -- Remove iOS codesigning sdk restriction in setting preset [#414](https://github.com/yonaskolb/XcodeGen/pull/414) @yonaskolb -- Changed default project version to Xcode 10.0 and default Swift version to 4.2 [#423](https://github.com/yonaskolb/XcodeGen/pull/423) @yonaskolb -- Added ability to not link Carthage frameworks [#432](https://github.com/yonaskolb/XcodeGen/pull/432) @yonaskolb +- Performance improvements for large projects #388 @yonaskolb @kastiglione +- Upgraded to xcodeproj 6 #388 @yonaskolb +- Upgraded to Swift 4.2 #388 @yonaskolb +- Remove iOS codesigning sdk restriction in setting preset #414 @yonaskolb +- Changed default project version to Xcode 10.0 and default Swift version to 4.2 #423 @yonaskolb +- Added ability to not link Carthage frameworks #432 @yonaskolb #### Fixed -- Fixed code signing issues [#414](https://github.com/yonaskolb/XcodeGen/pull/414) @yonaskolb -- Fixed `TargetSource.headerVisibility` not being set in initializer [#419](https://github.com/yonaskolb/XcodeGen/pull/419) @jerrymarino -- Fixed crash when using Xcode Legacy targets as dependencies [#427](https://github.com/yonaskolb/XcodeGen/pull/427) @dflems +- Fixed code signing issues #414 @yonaskolb +- Fixed `TargetSource.headerVisibility` not being set in initializer #419 @jerrymarino +- Fixed crash when using Xcode Legacy targets as dependencies #427 @dflems [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.2...2.0.0) @@ -583,13 +583,13 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project will not be deterministic. This will be fixed in an upcoming release with an update to xcodeproj 6.0 #### Fixed -- Fixed release builds in Swift 4.2 [#404](https://github.com/yonaskolb/XcodeGen/pull/404) @pepibumur -- Fixed default settings for macOS unit-tests [#387](https://github.com/yonaskolb/XcodeGen/pull/387) @frankdilo -- Fixed Copy Headers phase ordering for Xcode 10 [#401](https://github.com/yonaskolb/XcodeGen/pull/401) @brentleyjones -- Fixed generated schemes on aggregate targets [#394](https://github.com/yonaskolb/XcodeGen/pull/394) @vgorloff +- Fixed release builds in Swift 4.2 #404 @pepibumur +- Fixed default settings for macOS unit-tests #387 @frankdilo +- Fixed Copy Headers phase ordering for Xcode 10 #401 @brentleyjones +- Fixed generated schemes on aggregate targets #394 @vgorloff #### Changed -- Added `en` as default value for knownRegions [#390](https://github.com/yonaskolb/XcodeGen/pull/390) @Saik0s +- Added `en` as default value for knownRegions #390 @Saik0s - Update `PathKit`, `Spectre`, `Yams` and `xcodeproj` dependencies [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.1...1.11.2) @@ -597,43 +597,43 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.11.1 #### Fixed -- Fixed `FRAMEWORK_SEARCH_PATHS` for `framework` dependency paths with spaces [#382](https://github.com/yonaskolb/XcodeGen/pull/382) @brentleyjones -- Fixed aggregate targets not being found with `transitivelyLinkDependencies` [#383](https://github.com/yonaskolb/XcodeGen/pull/383) @brentleyjones +- Fixed `FRAMEWORK_SEARCH_PATHS` for `framework` dependency paths with spaces #382 @brentleyjones +- Fixed aggregate targets not being found with `transitivelyLinkDependencies` #383 @brentleyjones [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.0...1.11.1) ## 1.11.0 #### Added -- Added `showEnvVars` to build scripts to disable printing the environment [#351](https://github.com/yonaskolb/XcodeGen/pull/351) @keith -- Added `requiresObjCLinking` to `target` [#354](https://github.com/yonaskolb/XcodeGen/pull/354) @brentleyjones -- Added `targetTemplates` [#355](https://github.com/yonaskolb/XcodeGen/pull/355) @yonaskolb -- Added `aggregateTargets` [#353](https://github.com/yonaskolb/XcodeGen/pull/353) [#381](https://github.com/yonaskolb/XcodeGen/pull/381) @yonaskolb -- Added `options.groupSortPosition` [#356](https://github.com/yonaskolb/XcodeGen/pull/356) @yonaskolb -- Added ability to specify `copyFiles` build phase for sources [#345](https://github.com/yonaskolb/XcodeGen/pull/345) @brentleyjones -- Added ability to specify a `minimumXcodeGenVersion` [#349](https://github.com/yonaskolb/XcodeGen/pull/349) @brentleyjones -- Added `customArchiveName` and `revealArchiveInOrganizer` to `archive` [#367](https://github.com/yonaskolb/XcodeGen/pull/367) @sxua +- Added `showEnvVars` to build scripts to disable printing the environment #351 @keith +- Added `requiresObjCLinking` to `target` #354 @brentleyjones +- Added `targetTemplates` #355 @yonaskolb +- Added `aggregateTargets` #353 @yonaskolb +- Added `options.groupSortPosition` #356 @yonaskolb +- Added ability to specify `copyFiles` build phase for sources #345 @brentleyjones +- Added ability to specify a `minimumXcodeGenVersion` #349 @brentleyjones +- Added `customArchiveName` and `revealArchiveInOrganizer` to `archive` #367 @sxua #### Fixed -- Sort files using localizedStandardCompare [#341](https://github.com/yonaskolb/XcodeGen/pull/341) @rohitpal440 -- Use the latest `xcdatamodel` when sorted by version [#341](https://github.com/yonaskolb/XcodeGen/pull/341) @rohitpal440 -- Fixed compiler flags being set on non source files in mixed build phase target sources [#347](https://github.com/yonaskolb/XcodeGen/pull/347) @brentleyjones -- Fixed `options.xcodeVersion` not being parsed [#348](https://github.com/yonaskolb/XcodeGen/pull/348) @brentleyjones -- Fixed non-application targets using `carthage copy-frameworks` [#361](https://github.com/yonaskolb/XcodeGen/pull/361) @brentleyjones -- Set `xcdatamodel` based on `xccurrentversion` if available [#364](https://github.com/yonaskolb/XcodeGen/pull/364) @rpassis -- XPC Services are now correctly copied [#368](https://github.com/yonaskolb/XcodeGen/pull/368) @brentley -- Fixed `.metal` files being added to resources [#380](https://github.com/yonaskolb/XcodeGen/pull/380) @vgorloff +- Sort files using localizedStandardCompare #341 @rohitpal440 +- Use the latest `xcdatamodel` when sorted by version #341 @rohitpal440 +- Fixed compiler flags being set on non source files in mixed build phase target sources #347 @brentleyjones +- Fixed `options.xcodeVersion` not being parsed #348 @brentleyjones +- Fixed non-application targets using `carthage copy-frameworks` #361 @brentleyjones +- Set `xcdatamodel` based on `xccurrentversion` if available #364 @rpassis +- XPC Services are now correctly copied #368 @brentley +- Fixed `.metal` files being added to resources #380 @vgorloff #### Changed -- Improved linking for `static.library` targets [#352](https://github.com/yonaskolb/XcodeGen/pull/352) @brentleyjones -- Changed default group sorting to be after files [#356](https://github.com/yonaskolb/XcodeGen/pull/356) @yonaskolb -- Moved `Frameworks` and `Products` top level groups to bottom [#356](https://github.com/yonaskolb/XcodeGen/pull/356) @yonaskolb -- `modulemap` files are automatically copied to the products directory for static library targets [#346](https://github.com/yonaskolb/XcodeGen/pull/346) @brentleyjones -- Public header files are automatically copied to the products directory for static library targets [#365](https://github.com/yonaskolb/XcodeGen/pull/365) @brentleyjones -- Swift Objective-C Interface Header files are automatically copied to the products directory for static library targets [#366](https://github.com/yonaskolb/XcodeGen/pull/366) @brentleyjones -- `FRAMEWORK_SEARCH_PATHS` are adjusted for `framework` dependencies [#373](https://github.com/yonaskolb/XcodeGen/pull/373) @brentley -- `library.static` targets have `SKIP_INSTALL` set to `YES` [#358](https://github.com/yonaskolb/XcodeGen/pull/358) @brentley -- Copy files phases have descriptive names [#360](https://github.com/yonaskolb/XcodeGen/pull/360) @brentley +- Improved linking for `static.library` targets #352 @brentleyjones +- Changed default group sorting to be after files #356 @yonaskolb +- Moved `Frameworks` and `Products` top level groups to bottom #356 @yonaskolb +- `modulemap` files are automatically copied to the products directory for static library targets #346 @brentleyjones +- Public header files are automatically copied to the products directory for static library targets #365 @brentleyjones +- Swift Objective-C Interface Header files are automatically copied to the products directory for static library targets #366 @brentleyjones +- `FRAMEWORK_SEARCH_PATHS` are adjusted for `framework` dependencies #373 @brentley +- `library.static` targets have `SKIP_INSTALL` set to `YES` #358 @brentley +- Copy files phases have descriptive names #360 @brentley #### Internal - Moved brew formula to homebrew core @@ -644,7 +644,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.10.3 #### Fixed -- Fixed Mint installations finding `SettingPresets` [#338](https://github.com/yonaskolb/XcodeGen/pull/338) @yonaskolb +- Fixed Mint installations finding `SettingPresets` #338 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.2...1.10.3) @@ -658,72 +658,72 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.10.1 #### Fixed -- Fixed `transitivelyLinkDependencies` typo [#332](https://github.com/yonaskolb/XcodeGen/pull/332) @brentleyjones -- Fixed framework target dependencies not being code signed by default [#332](https://github.com/yonaskolb/XcodeGen/pull/332) @yonaskolb +- Fixed `transitivelyLinkDependencies` typo #332 @brentleyjones +- Fixed framework target dependencies not being code signed by default #332 @yonaskolb #### Changed -- Code sign all dependencies by default except target executables [#332](https://github.com/yonaskolb/XcodeGen/pull/332) @yonaskolb +- Code sign all dependencies by default except target executables #332 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.0...1.10.1) ## 1.10.0 #### Added -- Added build rule support [#306](https://github.com/yonaskolb/XcodeGen/pull/306) @yonaskolb -- Added support for frameworks in sources [#308](https://github.com/yonaskolb/XcodeGen/pull/308) @keith -- Added ability to automatically embed transient dependencies. Controlled with `transitivelyLinkDependencies` [#327](https://github.com/yonaskolb/XcodeGen/pull/327) @brentleyjones +- Added build rule support #306 @yonaskolb +- Added support for frameworks in sources #308 @keith +- Added ability to automatically embed transient dependencies. Controlled with `transitivelyLinkDependencies` #327 @brentleyjones #### Changed - Upgraded to Swift 4.1 -- Improved Carthage dependency lookup performance with many targets [#298](https://github.com/yonaskolb/XcodeGen/pull/298) @keith -- By default don't CodeSignOnCopy `target` dependencies. This can still be controlled with `Dependency.codeSign` [#324](https://github.com/yonaskolb/XcodeGen/pull/324) @yonaskolb +- Improved Carthage dependency lookup performance with many targets #298 @keith +- By default don't CodeSignOnCopy `target` dependencies. This can still be controlled with `Dependency.codeSign` #324 @yonaskolb #### Fixed -- Fixed PBXBuildFile and PBXFileReference being incorrectly generated for Legacy targets [#296](https://github.com/yonaskolb/XcodeGen/pull/296) @sascha -- Fixed required sources build phase not being generated if there are no sources [#307](https://github.com/yonaskolb/XcodeGen/pull/307) @yonaskolb -- Fixed install script in binary release [#303](https://github.com/yonaskolb/XcodeGen/pull/303) @alvarhansen -- Removed `ENABLE_TESTABILITY` from framework setting presets [#299](https://github.com/yonaskolb/XcodeGen/pull/299) @allu22 -- Fixed homebrew installation [#297](https://github.com/yonaskolb/XcodeGen/pull/297) @vhbit -- `cc` files are now automatically recognized as source files [#317](https://github.com/yonaskolb/XcodeGen/pull/317) @maicki -- Fixed `commandLineArguments` not parsing when they had dots in them [#323](https://github.com/yonaskolb/XcodeGen/pull/323) @yonaskolb -- Fixed excluding directories that only have sub directories [#326](https://github.com/yonaskolb/XcodeGen/pull/326) @brentleyjones +- Fixed PBXBuildFile and PBXFileReference being incorrectly generated for Legacy targets #296 @sascha +- Fixed required sources build phase not being generated if there are no sources #307 @yonaskolb +- Fixed install script in binary release #303 @alvarhansen +- Removed `ENABLE_TESTABILITY` from framework setting presets #299 @allu22 +- Fixed homebrew installation #297 @vhbit +- `cc` files are now automatically recognized as source files #317 @maicki +- Fixed `commandLineArguments` not parsing when they had dots in them #323 @yonaskolb +- Fixed excluding directories that only have sub directories #326 @brentleyjones - Made `PBXContainerItemProxy` ID more deterministic -- Fixed generated framework schemes from being executable [#328](https://github.com/yonaskolb/XcodeGen/pull/328) @brentleyjones +- Fixed generated framework schemes from being executable #328 @brentleyjones [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.9.0...1.10.0) ## 1.9.0 #### Added -- Scheme pre and post actions can now be added to `target.scheme` [#280](https://github.com/yonaskolb/XcodeGen/pull/280) @yonaskolb -- Individual files can now be added to `fileGroups` [#293](https://github.com/yonaskolb/XcodeGen/pull/293) @yonaskolb +- Scheme pre and post actions can now be added to `target.scheme` #280 @yonaskolb +- Individual files can now be added to `fileGroups` #293 @yonaskolb #### Changed - Updated to `xcproj` 4.3.0 for Xcode 9.3 updates -- Update default Xcode version to 9.3 including new settings [#284](https://github.com/yonaskolb/XcodeGen/pull/284) @LinusU -- **Breaking for ProjectSpec library users** Changed `ProjectSpec` to `Project` and `ProjectSpec.Options` to `SpecOptions` [#281](https://github.com/yonaskolb/XcodeGen/pull/281) @jerrymarino +- Update default Xcode version to 9.3 including new settings #284 @LinusU +- **Breaking for ProjectSpec library users** Changed `ProjectSpec` to `Project` and `ProjectSpec.Options` to `SpecOptions` #281 @jerrymarino #### Fixed -- Fixed manual build phase of `none` not being applied to folders [#288](https://github.com/yonaskolb/XcodeGen/pull/288) @yonaskolb -- Quoted values now correctly get parsed as strings [#282](https://github.com/yonaskolb/XcodeGen/pull/282) @yonaskolb -- Fixed adding a root source folder when `createIntermediateGroups` is on [#291](https://github.com/yonaskolb/XcodeGen/pull/291) @yonaskolb -- Fixed Homebrew installations issues on some machines [#289](https://github.com/yonaskolb/XcodeGen/pull/289) @vhbit -- Fixed files that are added as root sources from having invalid parent groups outside the project directory [#293](https://github.com/yonaskolb/XcodeGen/pull/293) @yonaskolb +- Fixed manual build phase of `none` not being applied to folders #288 @yonaskolb +- Quoted values now correctly get parsed as strings #282 @yonaskolb +- Fixed adding a root source folder when `createIntermediateGroups` is on #291 @yonaskolb +- Fixed Homebrew installations issues on some machines #289 @vhbit +- Fixed files that are added as root sources from having invalid parent groups outside the project directory #293 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.8.0...1.9.0) ## 1.8.0 #### Added -- Added Project `defaultConfig` [#269](https://github.com/yonaskolb/XcodeGen/pull/269) @keith -- Added Target `attributes` [#276](https://github.com/yonaskolb/XcodeGen/pull/276) @yonaskolb -- Automatically set `DevelopmentTeam` and `ProvisioningStyle` within `TargetAttributes` if relevant build settings are defined [#277](https://github.com/yonaskolb/XcodeGen/pull/277) @yonaskolb +- Added Project `defaultConfig` #269 @keith +- Added Target `attributes` #276 @yonaskolb +- Automatically set `DevelopmentTeam` and `ProvisioningStyle` within `TargetAttributes` if relevant build settings are defined #277 @yonaskolb #### Fixed -- Fixed default `LD_RUNPATH_SEARCH_PATHS` for app extensions [#272](https://github.com/yonaskolb/XcodeGen/pull/272) @LinusU +- Fixed default `LD_RUNPATH_SEARCH_PATHS` for app extensions #272 @LinusU #### Internal -- Make `LegacyTarget` init public [#264](https://github.com/yonaskolb/XcodeGen/pull/264) @jerrymarino +- Make `LegacyTarget` init public #264 @jerrymarino - Upgrade to *xcproj* to 4.2.0, *Yams* to 0.6.0 and *PathKit* to 0.9.1 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.7.0...1.8.0) @@ -732,113 +732,113 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Added -- Added support for scheme environment variables [#239](https://github.com/yonaskolb/XcodeGen/pull/239) [#254](https://github.com/yonaskolb/XcodeGen/pull/254) [#259](https://github.com/yonaskolb/XcodeGen/pull/259) @turekj @toshi0383 -- Added `carthageExecutablePath` option [#244](https://github.com/yonaskolb/XcodeGen/pull/244) @akkyie -- Added `parallelizeBuild` and `buildImplicitDependencies` to Schemes [#241](https://github.com/yonaskolb/XcodeGen/pull/241) @rahul-malik +- Added support for scheme environment variables #239 @turekj @toshi0383 +- Added `carthageExecutablePath` option #244 @akkyie +- Added `parallelizeBuild` and `buildImplicitDependencies` to Schemes #241 @rahul-malik @yonaskolb -- Added support for Core Data `xcdatamodeld` files [#249](https://github.com/yonaskolb/XcodeGen/pull/249) @yonaskolb -- Projects are now generated atomically by writing to a temporary directory first [#250](https://github.com/yonaskolb/XcodeGen/pull/250) @yonaskolb -- Added script for adding precompiled binary to releases [#246](https://github.com/yonaskolb/XcodeGen/pull/246) @toshi0383 -- Added optional `headerVisibilty` to target source. This still defaults to public [#252](https://github.com/yonaskolb/XcodeGen/pull/252) @yonaskolb +- Added support for Core Data `xcdatamodeld` files #249 @yonaskolb +- Projects are now generated atomically by writing to a temporary directory first #250 @yonaskolb +- Added script for adding precompiled binary to releases #246 @toshi0383 +- Added optional `headerVisibilty` to target source. This still defaults to public #252 @yonaskolb - Releases now include a pre-compiled binary and setting presets, including an install script #### Fixed -- Fixed Mint installation from reading setting presets [#248](https://github.com/yonaskolb/XcodeGen/pull/248) @yonaskolb -- Fixed setting `buildPhase` on a `folder` source. This allows for a folder of header files [#254](https://github.com/yonaskolb/XcodeGen/pull/254) @toshi0383 -- Carthage dependencies are not automatically embedded into test targets [#256](https://github.com/yonaskolb/XcodeGen/pull/256) @yonaskolb -- Carthage dependencies now respect the `embed` property [#256](https://github.com/yonaskolb/XcodeGen/pull/256) @yonaskolb -- iMessage extensions now have proper setting presets in regards to app icon and runtime search paths [#255](https://github.com/yonaskolb/XcodeGen/pull/255) @yonaskolb -- Excluded files are not added within .lproj directories [#238](https://github.com/yonaskolb/XcodeGen/pull/238) @toshi0383 +- Fixed Mint installation from reading setting presets #248 @yonaskolb +- Fixed setting `buildPhase` on a `folder` source. This allows for a folder of header files #254 @toshi0383 +- Carthage dependencies are not automatically embedded into test targets #256 @yonaskolb +- Carthage dependencies now respect the `embed` property #256 @yonaskolb +- iMessage extensions now have proper setting presets in regards to app icon and runtime search paths #255 @yonaskolb +- Excluded files are not added within .lproj directories #238 @toshi0383 [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.6.0...1.7.0) ## 1.6.0 #### Added -- Added scheme pre-actions and post-actions [#231](https://github.com/yonaskolb/XcodeGen/pull/231) @kastiglione -- Added `options.disabledValidations` including `missingConfigs` to disable project validation errors [#220](https://github.com/yonaskolb/XcodeGen/pull/220) @keith -- Generate UI Test Target Attributes [#221](https://github.com/yonaskolb/XcodeGen/pull/221) @anreitersimon +- Added scheme pre-actions and post-actions #231 @kastiglione +- Added `options.disabledValidations` including `missingConfigs` to disable project validation errors #220 @keith +- Generate UI Test Target Attributes #221 @anreitersimon #### Fixed -- Filter out duplicate source files [#217](https://github.com/yonaskolb/XcodeGen/pull/217) @allu22 -- Fixed how `lastKnownFileType` and `explicitFileType` were generated across platforms [#115](https://github.com/yonaskolb/XcodeGen/pull/115) @toshi0383 +- Filter out duplicate source files #217 @allu22 +- Fixed how `lastKnownFileType` and `explicitFileType` were generated across platforms #115 @toshi0383 - Removed a few cases of project diffs when opening the project in Xcode @yonaskolb - Fixed Swift not being embedded by default in watch apps @yonaskolb #### Changed -- Change arrays to strings in setting presets [#218](https://github.com/yonaskolb/XcodeGen/pull/218) @allu22 -- Updated to xcproj 4.0 [#227](https://github.com/yonaskolb/XcodeGen/pull/227) +- Change arrays to strings in setting presets #218 @allu22 +- Updated to xcproj 4.0 #227 [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.5.0...1.6.0) ## 1.5.0 #### Added -- added support for `gatherCoverageData` flag in target schemes [#170](https://github.com/yonaskolb/XcodeGen/pull/170) @alexruperez -- added support for `commandLineOptions` in target schemes [#172](https://github.com/yonaskolb/XcodeGen/pull/172) @rahul-malik -- added Project spec as a SwiftPM library for reuse in other projects [#164](https://github.com/yonaskolb/XcodeGen/pull/164) @soffes -- added `implicit` option for framework dependencies [#166](https://github.com/yonaskolb/XcodeGen/pull/166) @sbarow -- added `--quite` option to CLI [#167](https://github.com/yonaskolb/XcodeGen/pull/167) @soffes -- can now print version with `-v` in addition to `--version` [#174](https://github.com/yonaskolb/XcodeGen/pull/174) @kastiglione -- added support for legacy targets [#175](https://github.com/yonaskolb/XcodeGen/pull/175) @bkase -- added support for indentation options [#190](https://github.com/yonaskolb/XcodeGen/pull/190) @bkase -- added source excludes [#135](https://github.com/yonaskolb/XcodeGen/pull/135) [#161](https://github.com/yonaskolb/XcodeGen/pull/161) [#190](https://github.com/yonaskolb/XcodeGen/pull/190) @peymankh @ -- added `options.xcodeVersion` [#197](https://github.com/yonaskolb/XcodeGen/pull/197) @yonaskolb @peymankh -- add test targets to Scheme [#195](https://github.com/yonaskolb/XcodeGen/pull/195) @vhbit -- add option to make a source file optional incase it will be generated later [#200](https://github.com/yonaskolb/XcodeGen/pull/200) @vhbit -- finalize Scheme spec [#201](https://github.com/yonaskolb/XcodeGen/pull/201) @yonaskolb -- added `buildPhase` setting to target source for overriding the guessed build phase of files [#206](https://github.com/yonaskolb/XcodeGen/pull/206) @yonaskolb -- added `deploymentTarget` setting to project and target [#205](https://github.com/yonaskolb/XcodeGen/pull/205) @yonaskolb +- added support for `gatherCoverageData` flag in target schemes #170 @alexruperez +- added support for `commandLineOptions` in target schemes #172 @rahul-malik +- added Project spec as a SwiftPM library for reuse in other projects #164 @soffes +- added `implicit` option for framework dependencies #166 @sbarow +- added `--quite` option to CLI #167 @soffes +- can now print version with `-v` in addition to `--version` #174 @kastiglione +- added support for legacy targets #175 @bkase +- added support for indentation options #190 @bkase +- added source excludes #135 @peymankh @ +- added `options.xcodeVersion` #197 @yonaskolb @peymankh +- add test targets to Scheme #195 @vhbit +- add option to make a source file optional incase it will be generated later #200 @vhbit +- finalize Scheme spec #201 @yonaskolb +- added `buildPhase` setting to target source for overriding the guessed build phase of files #206 @yonaskolb +- added `deploymentTarget` setting to project and target #205 @yonaskolb #### Changed - huge performance improvements when writing the project file due to changes in xcproj - updated dependencies - minor logging changes - updated Project Spec documentation -- scan for `Info.plist` lazely [#194](https://github.com/yonaskolb/XcodeGen/pull/194) @kastiglione -- change setting presets so that icon settings only get applied to application targets [#204](https://github.com/yonaskolb/XcodeGen/pull/204) @yonaskolb -- changed scheme build targets format [#203](https://github.com/yonaskolb/XcodeGen/pull/203) @yonaskolb -- when specifying a `--spec` argument, the default for the `--project` path is now the directory containing the spec [#211](https://github.com/yonaskolb/XcodeGen/pull/211) @yonaskolb +- scan for `Info.plist` lazely #194 @kastiglione +- change setting presets so that icon settings only get applied to application targets #204 @yonaskolb +- changed scheme build targets format #203 @yonaskolb +- when specifying a `--spec` argument, the default for the `--project` path is now the directory containing the spec #211 @yonaskolb #### Fixed -- fixed shell scripts escaping quotes twice [#186](https://github.com/yonaskolb/XcodeGen/pull/186) @allu22 -- fixed `createIntermediateGroups` when using a relative spec path [#184](https://github.com/yonaskolb/XcodeGen/pull/184) @kastiglione -- fixed command line arguments for test and profile from being overridden [#199](https://github.com/yonaskolb/XcodeGen/pull/199) @vhbit +- fixed shell scripts escaping quotes twice #186 @allu22 +- fixed `createIntermediateGroups` when using a relative spec path #184 @kastiglione +- fixed command line arguments for test and profile from being overridden #199 @vhbit - fixed files deep within a hierarchy having the path for a name -- fixed source files from being duplicated if referenced with different casing [#212](https://github.com/yonaskolb/XcodeGen/pull/212) @yonaskolb -- fixed target product name not being written. Fixes integration with R.swift [#213](https://github.com/yonaskolb/XcodeGen/pull/213) @yonaskolb +- fixed source files from being duplicated if referenced with different casing #212 @yonaskolb +- fixed target product name not being written. Fixes integration with R.swift #213 @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.4.0...1.5.0) ## 1.4.0 #### Added -- added `--version` flag [#112](https://github.com/yonaskolb/XcodeGen/pull/112) @mironal -- added support for adding individual file sources [#106](https://github.com/yonaskolb/XcodeGen/pull/106) [#133](https://github.com/yonaskolb/XcodeGen/pull/133) [#142](https://github.com/yonaskolb/XcodeGen/pull/142) [#139](https://github.com/yonaskolb/XcodeGen/pull/139) @bkase -- added source compiler flag support [#121](https://github.com/yonaskolb/XcodeGen/pull/121) @bkase -- added `ProjectSpec.options.createIntermediateGroups` [#108](https://github.com/yonaskolb/XcodeGen/pull/108) @bkase -- added better json loading support [#127](https://github.com/yonaskolb/XcodeGen/pull/127) @rahul-malik -- added source `name` for customizing names of source directories and file [#146](https://github.com/yonaskolb/XcodeGen/pull/146) @yonaskolb -- added folder reference source support via a new `type` property [#151](https://github.com/yonaskolb/XcodeGen/pull/151) @yonaskolb -- added `ProjectSpec.options.developmentLanguage` [#155](https://github.com/yonaskolb/XcodeGen/pull/155) @yonaskolb +- added `--version` flag #112 @mironal +- added support for adding individual file sources #106 @bkase +- added source compiler flag support #121 @bkase +- added `ProjectSpec.options.createIntermediateGroups` #108 @bkase +- added better json loading support #127 @rahul-malik +- added source `name` for customizing names of source directories and file #146 @yonaskolb +- added folder reference source support via a new `type` property #151 @yonaskolb +- added `ProjectSpec.options.developmentLanguage` #155 @yonaskolb #### Changed -- updated to xcproj 1.2.0 [#113](https://github.com/yonaskolb/XcodeGen/pull/113) @yonaskolb -- build settings from presets will be removed if they are provided in `xcconfig` files [#77](https://github.com/yonaskolb/XcodeGen/pull/77) @toshi0383 -- all files and groups are sorted by type and then alphabetically [#144](https://github.com/yonaskolb/XcodeGen/pull/144) @yonaskolb -- target sources can now have an expanded form [#119](https://github.com/yonaskolb/XcodeGen/pull/119) @yonaskolb -- empty build phases are now not generated [#149](https://github.com/yonaskolb/XcodeGen/pull/149) @yonaskolb -- make UUIDs more deterministic [#154](https://github.com/yonaskolb/XcodeGen/pull/154) @yonaskolb +- updated to xcproj 1.2.0 #113 @yonaskolb +- build settings from presets will be removed if they are provided in `xcconfig` files #77 @toshi0383 +- all files and groups are sorted by type and then alphabetically #144 @yonaskolb +- target sources can now have an expanded form #119 @yonaskolb +- empty build phases are now not generated #149 @yonaskolb +- make UUIDs more deterministic #154 @yonaskolb #### Fixed -- only add headers to frameworks and libraries [#118](https://github.com/yonaskolb/XcodeGen/pull/118) @ryohey -- fixed localized files with the same name [#126](https://github.com/yonaskolb/XcodeGen/pull/126) @ryohey -- fix intermediate sources [#144](https://github.com/yonaskolb/XcodeGen/pull/144) @yonaskolb -- fix cyclical target dependencies not working [#147](https://github.com/yonaskolb/XcodeGen/pull/147) @yonaskolb -- fix directory bundles not being added properly when referenced directly [#148](https://github.com/yonaskolb/XcodeGen/pull/1478) @yonaskolb -- made `mm`, `c` and `S` file be parsed as source files [#120](https://github.com/yonaskolb/XcodeGen/pull/120) [#125](https://github.com/yonaskolb/XcodeGen/pull/125) [#138](https://github.com/yonaskolb/XcodeGen/pull/138) @bkase @enmiller -- fix the generation of localized variant groups if there is no `Base.lproj` [#157](https://github.com/yonaskolb/XcodeGen/pull/157) @ryohey -- all localizations found are added to a projects known regions [#157](https://github.com/yonaskolb/XcodeGen/pull/157) @ryohey +- only add headers to frameworks and libraries #118 @ryohey +- fixed localized files with the same name #126 @ryohey +- fix intermediate sources #144 @yonaskolb +- fix cyclical target dependencies not working #147 @yonaskolb +- fix directory bundles not being added properly when referenced directly #148 @yonaskolb +- made `mm`, `c` and `S` file be parsed as source files #120 @bkase @enmiller +- fix the generation of localized variant groups if there is no `Base.lproj` #157 @ryohey +- all localizations found are added to a projects known regions #157 @ryohey #### Internal - refactoring @@ -850,26 +850,26 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.3.0 #### Added -- generate output files for Carthage copy-frameworks script [#84](https://github.com/yonaskolb/XcodeGen/pull/84) @mironal -- added options.settingPreset to choose which setting presets get applied [#100](https://github.com/yonaskolb/XcodeGen/pull/101) @yonaskolb -- added `link` option for target dependencies [#109](https://github.com/yonaskolb/XcodeGen/pull/109) @keith +- generate output files for Carthage copy-frameworks script #84 @mironal +- added options.settingPreset to choose which setting presets get applied #100 @yonaskolb +- added `link` option for target dependencies #109 @keith #### Changed -- updated to xcproj 0.4.1 [#85](https://github.com/yonaskolb/XcodeGen/pull/85) @enmiller -- don't copy base settings if config type has been left out [#100](https://github.com/yonaskolb/XcodeGen/pull/100) @yonaskolb -- generate localised files under a single variant group [#70](https://github.com/yonaskolb/XcodeGen/pull/70) @ryohey -- don't apply common project settings to configs with no type [#100](https://github.com/yonaskolb/XcodeGen/pull/100) @yonaskolb -- config references in settings can now be partially matched and are case insensitive [#111](https://github.com/yonaskolb/XcodeGen/pull/111) @yonaskolb +- updated to xcproj 0.4.1 #85 @enmiller +- don't copy base settings if config type has been left out #100 @yonaskolb +- generate localised files under a single variant group #70 @ryohey +- don't apply common project settings to configs with no type #100 @yonaskolb +- config references in settings can now be partially matched and are case insensitive #111 @yonaskolb - other small internal changes @yonaskolb #### Fixed -- embed Carthage frameworks for macOS [#82](https://github.com/yonaskolb/XcodeGen/pull/82) @toshi0383 -- fixed copying of watchOS app resources [#96](https://github.com/yonaskolb/XcodeGen/pull/96) @keith -- automatically ignore more file types for a target's sources (entitlements, gpx, apns) [#94](https://github.com/yonaskolb/XcodeGen/pull/94) @keith -- change make build to a PHONY task [#98](https://github.com/yonaskolb/XcodeGen/pull/98) @keith -- allow copying of resource files from dependant targets [#95](https://github.com/yonaskolb/XcodeGen/pull/95) @keith -- fixed library linking [#93](https://github.com/yonaskolb/XcodeGen/pull/93) @keith -- fixed duplicate carthage file references [#107](https://github.com/yonaskolb/XcodeGen/pull/107) @yonaskolb +- embed Carthage frameworks for macOS #82 @toshi0383 +- fixed copying of watchOS app resources #96 @keith +- automatically ignore more file types for a target's sources (entitlements, gpx, apns) #94 @keith +- change make build to a PHONY task #98 @keith +- allow copying of resource files from dependant targets #95 @keith +- fixed library linking #93 @keith +- fixed duplicate carthage file references #107 @yonaskolb - an error is now shown if you try and generate a target scheme and don't have debug and release builds @yonaskolb [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.4...1.3.0) @@ -889,8 +889,8 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.2.3 #### Fixed -- Fixed wrong carthage directory name reference for macOS [#74](https://github.com/yonaskolb/XcodeGen/pull/74) @toshi0383 -- Removed unnecessary `carthage copy-frameworks` for macOS app target [#76](https://github.com/yonaskolb/XcodeGen/pull/76) @toshi0383 +- Fixed wrong carthage directory name reference for macOS #74 @toshi0383 +- Removed unnecessary `carthage copy-frameworks` for macOS app target #76 @toshi0383 - Added some missing default settings for framework targets. `SKIP_INSTALL: YES` fixes archiving - Filter out nulls from setting presets if specifying an empty string @@ -912,17 +912,17 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Added - `include` now supports a single string as well as a list -- add support setting xcconfig files on a project with `configFiles` [#64](https://github.com/yonaskolb/XcodeGen/pull/64) -- add `fileGroups` to project spec for adding groups of files that aren't target source files [#64](https://github.com/yonaskolb/XcodeGen/pull/64) +- add support setting xcconfig files on a project with `configFiles` #64 +- add `fileGroups` to project spec for adding groups of files that aren't target source files #64 - better output (more info, emoji, colors) -- add `options.bundleIdPrefix` for autogenerating `PRODUCT_BUNDLE_IDENTIFIER` [#67](https://github.com/yonaskolb/XcodeGen/pull/67) -- add `:REPLACE` syntax when merging `include` [#68](https://github.com/yonaskolb/XcodeGen/pull/68) +- add `options.bundleIdPrefix` for autogenerating `PRODUCT_BUNDLE_IDENTIFIER` #67 +- add `:REPLACE` syntax when merging `include` #68 - add `mint` installation support #### Fixed - fixed homebrew installation -- fixed target xcconfig files not working via `configFiles` [#64](https://github.com/yonaskolb/XcodeGen/pull/64) -- look for `INFOPLIST_FILE` setting in project and xcconfig files before adding it automatically. It was just looking in target settings before [#64](https://github.com/yonaskolb/XcodeGen/pull/64) +- fixed target xcconfig files not working via `configFiles` #64 +- look for `INFOPLIST_FILE` setting in project and xcconfig files before adding it automatically. It was just looking in target settings before #64 - exit with error on failure [Commits](https://github.com/yonaskolb/XcodeGen/compare/1.1.0...1.2.0) @@ -946,16 +946,16 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.0.0 #### Added -- Swift 4 support [#52](https://github.com/yonaskolb/XcodeGen/pull/52) -- Support for C and C++ files [#48](https://github.com/yonaskolb/XcodeGen/pull/48) by @antoniocasero +- Swift 4 support #52 +- Support for C and C++ files #48 by @antoniocasero - Xcode 9 default settings #### Fixed -- fixed empty string in YAML not being parsed properly [#50](https://github.com/yonaskolb/XcodeGen/pull/50) by @antoniocasero +- fixed empty string in YAML not being parsed properly #50 by @antoniocasero #### Changed -- updated to xcodeproj 0.1.2 [#56](https://github.com/yonaskolb/XcodeGen/pull/56) -- **BREAKING**: changed target definitions from list to map [#54](https://github.com/yonaskolb/XcodeGen/pull/54) See [Project Spec](docs/ProjectSpec.md) +- updated to xcodeproj 0.1.2 #56 +- **BREAKING**: changed target definitions from list to map #54 [Commits](https://github.com/yonaskolb/XcodeGen/compare/0.6.1...1.0.0) @@ -963,18 +963,18 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 0.6.1 #### Added -- Ability to set PBXProject attributes [#45](https://github.com/yonaskolb/XcodeGen/pull/45) +- Ability to set PBXProject attributes #45 #### Changed - Don't bother linking target frameworks for target dependencies. -- Move code signing default settings from all iOS targets to iOS application targets, via Product + Platform setting preset files [#46](https://github.com/yonaskolb/XcodeGen/pull/46) +- Move code signing default settings from all iOS targets to iOS application targets, via Product + Platform setting preset files #46 [Commits](https://github.com/yonaskolb/XcodeGen/compare/0.6.0...0.6.1) ## 0.6.0 #### Added -- Allow a project spec to include other project specs [#44](https://github.com/yonaskolb/XcodeGen/pull/44) +- Allow a project spec to include other project specs #44 #### Changed - Changed default spec path to `project.yml` @@ -987,16 +987,16 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Fixed - Fix embedded framework dependencies - Add `CODE_SIGN_IDENTITY[sdk=iphoneos*]` back to iOS targets -- Fix build scripts with "" generating invalid projects [#43](https://github.com/yonaskolb/XcodeGen/pull/43) +- Fix build scripts with "" generating invalid projects #43 [Commits](https://github.com/yonaskolb/XcodeGen/compare/0.5.0...0.5.1) ## 0.5.0 #### Added -- Added multi platform targets [#35](https://github.com/yonaskolb/XcodeGen/pull/35) -- Automatically generate platform specific `FRAMEWORK_SEARCH_PATHS` for Carthage dependencies [#38](https://github.com/yonaskolb/XcodeGen/pull/38) -- Automatically find Info.plist and set `INFOPLIST_FILE` build setting if it doesn't exist on a target [#40](https://github.com/yonaskolb/XcodeGen/pull/40) -- Add options for controlling embedding of dependencies [#37](https://github.com/yonaskolb/XcodeGen/pull/37) +- Added multi platform targets #35 +- Automatically generate platform specific `FRAMEWORK_SEARCH_PATHS` for Carthage dependencies #38 +- Automatically find Info.plist and set `INFOPLIST_FILE` build setting if it doesn't exist on a target #40 +- Add options for controlling embedding of dependencies #37 #### Fixed - Fixed localized files not being added to a target's resources @@ -1010,23 +1010,23 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 0.4.0 ##### Added -- Homebrew support [#16](https://github.com/yonaskolb/XcodeGen/pull/16) by @pepibumur -- Added `runOnlyWhenInstalling` to build scripts [#32](https://github.com/yonaskolb/XcodeGen/pull/32) -- Added `carthageBuildPath` option [#34](https://github.com/yonaskolb/XcodeGen/pull/34) +- Homebrew support #16 by @pepibumur +- Added `runOnlyWhenInstalling` to build scripts #32 +- Added `carthageBuildPath` option #34 #### Fixed - Fixed installations of XcodeGen not applying build setting presets for configs, products, and platforms, due to missing resources #### Changed -- Upgraded to https://github.com/swift-xcode/xcodeproj 0.1.1 [#33](https://github.com/yonaskolb/XcodeGen/pull/33) +- Upgraded to https://github.com/swift-xcode/xcodeproj 0.1.1 #33 [Commits](https://github.com/yonaskolb/XcodeGen/compare/0.3.0...0.4.0) ## 0.3.0 - Extensions and Scheme Tests #### Added -- Support for app extension dependencies, using the same `target: MyExtension` syntax [#19](https://github.com/yonaskolb/XcodeGen/pull/19) -- Added test targets to generated target schemes via `Target.scheme.testTargets` [#21](https://github.com/yonaskolb/XcodeGen/pull/21) +- Support for app extension dependencies, using the same `target: MyExtension` syntax #19 +- Added test targets to generated target schemes via `Target.scheme.testTargets` #21 #### Changed - Updated xcodeproj to 0.0.9 @@ -1042,7 +1042,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 0.2.0 - Build scripts #### Added -- Added Target build scripts with `Target.prebuildScripts` and `Target.postbuildScripts` [#17](https://github.com/yonaskolb/XcodeGen/pull/17) +- Added Target build scripts with `Target.prebuildScripts` and `Target.postbuildScripts` #17 - Support for absolute paths in target sources, run script files, and config files - Add validation for incorrect `Target.configFiles` From fd8aa8faf9918e8bb1b3e591d71bb23c378643f3 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Thu, 31 Mar 2022 16:43:32 +1100 Subject: [PATCH 36/55] simplify changelog and remove commit links github can compare diffs --- CHANGELOG.md | 123 +-------------------------------------------------- 1 file changed, 1 insertion(+), 122 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1de9098..3b8d9cac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,6 @@ - Run target source pattern matching in parallel #1197 @alvarhansen -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.27.0...2.28.0) - ## 2.27.0 #### Added @@ -32,8 +30,6 @@ - Fixed crash caused by a simultaneous write during a glob processing #1177 @tr1ckyf0x - Skip generating empty compile sources build phases for watch apps #1185 @evandcoleman -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.26.0...2.27.0) - ## 2.26.0 ### Added @@ -44,8 +40,6 @@ - Speed up source inclusion checking for big projects #1122 @PaulTaykalo -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.25.0...2.26.0) - ## 2.25.0 ### Added @@ -58,8 +52,6 @@ - Fix platform filter for package dependecies #1123 @raptorxcz - Fix Xcode 13 build #1130 @raptorxcz @mthole -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.24.0...2.25.0) - ### Changed - Update XcodeProj to 8.2.0 #1125 @nnsnodnb @@ -76,16 +68,12 @@ ### Changed - **Breaking**: Rename the `platform` field on `Dependency` to `platformFilter` #1087 @daltonclaybrook -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.23.1...2.24.0) - ## 2.23.1 ### Changed - Reverted "Change FRAMEWORK_SEARCH_PATH for xcframeworks (#1015)", introduced in 2.20.0. XCFrameworks need to be referenced directly in the project for Xcode's build system to extract the appropriate frameworks #1081 @elliottwilliams -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.23.0...2.23.1) - ## 2.23.0 #### Added @@ -95,8 +83,6 @@ - Added `()` to config variant trimming charater set to fix scheme config variant lookups for some configs like `Debug (Development)` that broke in 2.22.0 #1078 @DavidWoohyunLee - Fixed Linux builds on Swift 5.4 #1083 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.22.0...2.23.0) - ## 2.22.0 #### Added @@ -109,8 +95,6 @@ - Fixed no such module `DOT` error when package is used as a dependency #1067 @yanamura - Fixed scheme config variant lookups for some configs like `ProdDebug` and `Prod-Debug` that broke in 2.21.0 #1070 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.21.0...2.22.0) - ## 2.21.0 #### Added @@ -123,8 +107,6 @@ - The `Core` target is renamed to avoid collisions with other packages. #1057 @elliottwilliams - Lookup scheme config variants by whole words, fixing incorrect assignment in names that contain subtrings of each other (eg PreProd and Prod) #976 @stefanomondino -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.20.0...2.21.0) - ## 2.20.0 #### Added @@ -143,8 +125,6 @@ #### Internal - Build universal binaries for release. XcodeGen now runs natively on Apple Silicon. #1024 @thii -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.19.0...2.20.0) - ## 2.19.0 #### Added @@ -170,8 +150,6 @@ #### Internal - Updated to Yams 4.0.0 #984 @swiftty -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.18.0...2.19.0) - ## 2.18.0 #### Added @@ -195,8 +173,6 @@ - Fix appex's Runpath Search Paths under macOS target. #952 @rinsuki - `onlyCopyFilesOnInstall` is extended for the Embed App Extensions build phase. #948 @RomanPodymov -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.17.0...2.18.0) - ## 2.17.0 #### Added @@ -212,8 +188,6 @@ #### Internal - Updated to XcodeProj 7.13.0 #908 @brentleyjones -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.16.0...2.17.0) - ## 2.16.0 #### Added @@ -245,8 +219,6 @@ - Compile `xcmappingmodel` files instead of copying bundle resources. #834 @jcolicchio - Fixed issue where `Complie Sources` build phase is generated for resource bundles even when they have no files to compile #878 @nkukushkin -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.15.1...2.16.0) - ## 2.15.1 #### Fixed @@ -254,8 +226,6 @@ - Added build presets for the target type `framework.static`. #819 @acecilia - Fixed XcodeProj resolution and updated to 7.10.0 #822 @soffes -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.15.0...2.15.1) - ## 2.15.0 #### Added @@ -267,8 +237,6 @@ - Added ability to stop on every main thread checker issue on Run schemes and TargetSchemes #799 @ionutivan - Avoid copying ObjC interface header when SWIFT_INSTALL_OBJC_HEADER=false. #805 @kateinoigakukun -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.14.0...2.15.0) - ## 2.14.0 #### Added @@ -280,8 +248,6 @@ - Set `TEST_TARGET_NAME` only when a project has UITest bundle. #792 @ken0nek - Set xcodeproj path in project.xcworkspace/contents.xcworkspacedata #793 @ken0nek -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.13.1...2.14.0) - ## 2.13.1 #### Fixed @@ -293,8 +259,6 @@ - Updated to XcodeProj 7.8.0 #777 @yonaskolb - Use https://github.com/mxcl/Version #779 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.13.0...2.13.1) - ## 2.13.0 #### Added @@ -308,8 +272,6 @@ #### Internal - Updated to XcodeProj 7.7.0 #767 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.12.0...2.13.0) - ## 2.12.0 #### Added @@ -329,8 +291,6 @@ #### Internal - Update to SwiftCLI 6.0 and use the new property wrappers #749 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.11.0...2.12.0) - ## 2.11.0 #### Added @@ -353,8 +313,6 @@ - Updated XcodeProj to 7.4.0 #709 @yonaskolb - Updated to Swift 5.1 #714 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.10.1...2.11.0) - ## 2.10.1 #### Fixed @@ -362,8 +320,6 @@ - Fixed missing `onlyGenerateCoverageForSpecifiedTargets` issue #700 @kateinoigakukun - Fixed regression on dependencies `link` flag #703 @rcari -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.10.0...2.10.1) - ## 2.10.0 #### Added @@ -380,8 +336,6 @@ #### Internal - Restructure targets #698 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.9.0...2.10.0) - ## 2.9.0 #### Added @@ -397,8 +351,6 @@ - Updated to SwiftCLI 5.3.2 #667 @giginet - Fixed tests in case-sensitive file system #670 @Qusic -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.8.0...2.9.0) - ## 2.8.0 #### Added @@ -417,8 +369,6 @@ - Removed needless `Array` initialization. #661 @RomanPodymov - Updated to XcodeProj 7.1.0 #624 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.7.0...2.8.0) - ## 2.7.0 #### Added @@ -432,8 +382,6 @@ #### Changed - Allow linking of dependencies into static libraries when `link` is set to true #635 @kateinoigakukun -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.6.0...2.7.0) - ## 2.6.0 #### Added @@ -453,8 +401,6 @@ #### Internal - Added ability to encode ProjectSpec #545 @ryohey -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.5.0...2.6.0) - ## 2.5.0 #### Added @@ -472,8 +418,6 @@ - Fixed `optional` file sources not being added to the project #557 @yonaskolb - Fixed Carthage dependencies being incorrectly embedded in WatchKit app bundles instead of a WatchKit app extension #558 @KhaosT -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.4.0...2.5.0) - ## 2.4.0 #### Fixed: @@ -482,8 +426,6 @@ #### Changed - Updated to Swift 5 and dropped Swift 4.2 #549 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.3.0...2.4.0) - ## 2.3.0 #### Added @@ -505,8 +447,6 @@ - Fix multi-platform target templates #541 @yonaskolb - Fixed sources in an included target not being relative when the sources are mix of string and dictionaries #542 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.2.0...2.3.0) - ## 2.2.0 #### Added @@ -528,8 +468,6 @@ - Fixed generated schemes for tool targets not setting the executable #496 @yonaskolb - Fixed resolving Carthage dependencies for iOS app with watchOS target. [465](https://github.com/yonaskolb/XcodeGen/pull/465) @raptorxcz -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.1.0...2.2.0) - ## 2.1.0 #### Added @@ -550,8 +488,6 @@ - Add `.intentdefinition` files to sources build phase instead of resources #442 @yonaskolb - Add `mlmodel` files to sources build phase instead of resources #457 @dwb357 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.0.0...2.1.0) - ## 2.0.0 #### Added @@ -576,8 +512,6 @@ - Fixed `TargetSource.headerVisibility` not being set in initializer #419 @jerrymarino - Fixed crash when using Xcode Legacy targets as dependencies #427 @dflems -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.2...2.0.0) - ## 1.11.2 If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project will not be deterministic. This will be fixed in an upcoming release with an update to xcodeproj 6.0 @@ -592,16 +526,12 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Added `en` as default value for knownRegions #390 @Saik0s - Update `PathKit`, `Spectre`, `Yams` and `xcodeproj` dependencies -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.1...1.11.2) - ## 1.11.1 #### Fixed - Fixed `FRAMEWORK_SEARCH_PATHS` for `framework` dependency paths with spaces #382 @brentleyjones - Fixed aggregate targets not being found with `transitivelyLinkDependencies` #383 @brentleyjones -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.11.0...1.11.1) - ## 1.11.0 #### Added @@ -639,22 +569,16 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Moved brew formula to homebrew core - Added `CONTRIBUTING.md` -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.3...1.11.0) - ## 1.10.3 #### Fixed - Fixed Mint installations finding `SettingPresets` #338 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.2...1.10.3) - ## 1.10.2 #### Changed - Set `transitivelyLinkDependencies` to false by default -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.1...1.10.2) - ## 1.10.1 #### Fixed @@ -664,8 +588,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Changed - Code sign all dependencies by default except target executables #332 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.10.0...1.10.1) - ## 1.10.0 #### Added @@ -690,8 +612,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Made `PBXContainerItemProxy` ID more deterministic - Fixed generated framework schemes from being executable #328 @brentleyjones -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.9.0...1.10.0) - ## 1.9.0 #### Added @@ -710,8 +630,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Fixed Homebrew installations issues on some machines #289 @vhbit - Fixed files that are added as root sources from having invalid parent groups outside the project directory #293 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.8.0...1.9.0) - ## 1.8.0 #### Added @@ -726,8 +644,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Make `LegacyTarget` init public #264 @jerrymarino - Upgrade to *xcproj* to 4.2.0, *Yams* to 0.6.0 and *PathKit* to 0.9.1 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.7.0...1.8.0) - ## 1.7.0 #### Added @@ -750,8 +666,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - iMessage extensions now have proper setting presets in regards to app icon and runtime search paths #255 @yonaskolb - Excluded files are not added within .lproj directories #238 @toshi0383 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.6.0...1.7.0) - ## 1.6.0 #### Added @@ -769,8 +683,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Change arrays to strings in setting presets #218 @allu22 - Updated to xcproj 4.0 #227 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.5.0...1.6.0) - ## 1.5.0 #### Added @@ -808,8 +720,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - fixed source files from being duplicated if referenced with different casing #212 @yonaskolb - fixed target product name not being written. Fixes integration with R.swift #213 @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.4.0...1.5.0) - ## 1.4.0 #### Added @@ -845,8 +755,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - more tests - added release scripts -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.3.0...1.4.0) - ## 1.3.0 #### Added @@ -872,8 +780,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - fixed duplicate carthage file references #107 @yonaskolb - an error is now shown if you try and generate a target scheme and don't have debug and release builds @yonaskolb -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.4...1.3.0) - ## 1.2.4 #### Fixed @@ -884,8 +790,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Changed - update to xcproj 0.3.0 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.3...1.2.4) - ## 1.2.3 #### Fixed @@ -894,8 +798,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Added some missing default settings for framework targets. `SKIP_INSTALL: YES` fixes archiving - Filter out nulls from setting presets if specifying an empty string -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.2...1.2.3) - ## 1.2.2 #### Added @@ -906,8 +808,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - fixed tvOS launch screen setting. `ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME` is now `LaunchImage` not `tvOS LaunchImage` -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.2.0...1.2.2) - ## 1.2.0 #### Added @@ -925,24 +825,18 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - look for `INFOPLIST_FILE` setting in project and xcconfig files before adding it automatically. It was just looking in target settings before #64 - exit with error on failure -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.1.0...1.2.0) - ## 1.1.0 #### Changed - set project version to Xcode 9 - `LastUpgradeVersion` attribute to `0900` - set default Swift version to 4.0 - `SWIFT_VERSION` build setting to `4.0` -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.0.1...1.1.0) - ### 1.0.1 ### Fixed - fixed incorrect default build script shell path - fixed install scripts -[Commits](https://github.com/yonaskolb/XcodeGen/compare/1.0.0...1.0.1) - ## 1.0.0 #### Added @@ -958,8 +852,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - **BREAKING**: changed target definitions from list to map #54 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.6.1...1.0.0) - ## 0.6.1 #### Added @@ -969,8 +861,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Don't bother linking target frameworks for target dependencies. - Move code signing default settings from all iOS targets to iOS application targets, via Product + Platform setting preset files #46 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.6.0...0.6.1) - ## 0.6.0 #### Added @@ -980,8 +870,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Changed default spec path to `project.yml` - Changed default project directory to the current directory instead of the spec file's directory -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.5.1...0.6.0) - ## 0.5.1 #### Fixed @@ -989,8 +877,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Add `CODE_SIGN_IDENTITY[sdk=iphoneos*]` back to iOS targets - Fix build scripts with "" generating invalid projects #43 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.5.0...0.5.1) - ## 0.5.0 #### Added - Added multi platform targets #35 @@ -1005,8 +891,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Renamed Setting Presets to Setting Groups - Carthage group is now created under top level Frameworks group -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.4.0...0.5.0) - ## 0.4.0 ##### Added @@ -1020,8 +904,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Changed - Upgraded to https://github.com/swift-xcode/xcodeproj 0.1.1 #33 -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.3.0...0.4.0) - ## 0.3.0 - Extensions and Scheme Tests #### Added @@ -1037,8 +919,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Breaking changes - Changed `Target.generatedSchemes` to `Target.scheme.configVariants` -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.2...0.3.0) - ## 0.2.0 - Build scripts #### Added @@ -1049,7 +929,6 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil #### Fixed - Fixed some project objects sometimes having duplicate ids -[Commits](https://github.com/yonaskolb/XcodeGen/compare/0.1...0.2) - ## 0.1.0 First official release + From 047e9968d6e5308df73126d72cb42af8527a644c Mon Sep 17 00:00:00 2001 From: Yuya Hirayama Date: Tue, 5 Apr 2022 13:08:02 +0900 Subject: [PATCH 37/55] Fix docc support (#1202) * Update FileType.swift * Update SourceGeneratorTests.swift * Update fixture * Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ Sources/ProjectSpec/FileType.swift | 2 +- Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj | 2 ++ Tests/XcodeGenKitTests/SourceGeneratorTests.swift | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b8d9cac6..21fe20146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +#### Fixed + +- Fixed an issue where DocC was not added to source file list #1202 @hiragram + ## 2.28.0 #### Added diff --git a/Sources/ProjectSpec/FileType.swift b/Sources/ProjectSpec/FileType.swift index d106b2857..9fa9729b9 100644 --- a/Sources/ProjectSpec/FileType.swift +++ b/Sources/ProjectSpec/FileType.swift @@ -89,6 +89,7 @@ extension FileType { "mlmodel": FileType(buildPhase: .sources), "rcproject": FileType(buildPhase: .sources), "iig": FileType(buildPhase: .sources), + "docc": FileType(buildPhase: .sources), // headers "h": FileType(buildPhase: .headers), @@ -113,6 +114,5 @@ extension FileType { "xcfilelist": FileType(buildPhase: BuildPhaseSpec.none), "apns": FileType(buildPhase: BuildPhaseSpec.none), "pch": FileType(buildPhase: BuildPhaseSpec.none), - "docc": FileType(buildPhase: BuildPhaseSpec.none), ] } diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index f9df6bf94..2e610aaf8 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 1E03FC7312293997599C6435 /* Empty.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 068EDF47F0B087F6A4052AC0 /* Empty.h */; }; 1E2A4D61E96521FF7123D7B0 /* XPC Service.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 22237B8EBD9E6BE8EBC8735F /* XPC Service.xpc */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 1E457F55331FD2C3E8E00BE2 /* Result.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 1F9168A43FD8E2FCC2699E14 /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = B5C943D39DD7812CAB94B614 /* Documentation.docc */; settings = {COMPILER_FLAGS = "-Werror"; }; }; 210B49C23B9717C668B40C8C /* FrameworkFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5F527F2590C14956518174 /* FrameworkFile.swift */; }; 2116F89CF5A04EA0EFA30A89 /* TestProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D88C6BF7355702B74396791 /* TestProjectUITests.swift */; }; 212BCB51DAF3212993DDD49E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D51CC8BCCBD68A90E90A3207 /* Assets.xcassets */; }; @@ -2655,6 +2656,7 @@ buildActionMask = 2147483647; files = ( 09617AB755651FFEB2564CBC /* AppDelegate.swift in Sources */, + 1F9168A43FD8E2FCC2699E14 /* Documentation.docc in Sources */, 666DEC173BC78C7641AB22EC /* File1.swift in Sources */, 339578307B9266AB3D7722D9 /* File2.swift in Sources */, F788A3FA1CE6489BC257C1C3 /* Model.xcdatamodeld in Sources */, diff --git a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift index 3ef691027..e1121df7d 100644 --- a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift @@ -655,7 +655,7 @@ class SourceGeneratorTests: XCTestCase { try pbxProj.expectFileMissing(paths: ["C", "Settings.bundle", "Root.plist"]) try pbxProj.expectFileMissing(paths: ["C", "WithPeriod2.0"]) try pbxProj.expectFile(paths: ["C", "WithPeriod2.0", "file.swift"], buildPhase: .sources) - try pbxProj.expectFile(paths: ["C", "Documentation.docc"], buildPhase: BuildPhaseSpec.none) + try pbxProj.expectFile(paths: ["C", "Documentation.docc"], buildPhase: .sources) } $0.it("only omits the defined Info.plist from resource build phases but not other plists") { From e35f7df14d3884bf4cbd550aef1d8d60f9a14c11 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Tue, 10 May 2022 13:27:31 +1000 Subject: [PATCH 38/55] Add Test Plans (#716) * upgrade scheme and project versions * parse test plans * remove xctestplan from resources * generate test plan references in schemes * add test plan to fixture * non-mutable way of creating [XCScheme.TestPlanReference] * update fixture version * Add documentation * Add default test plan option # Conflicts: # Sources/ProjectSpec/Scheme.swift # Tests/Fixtures/paths_test/included_paths_test.yml # Tests/ProjectSpecTests/SpecLoadingTests.swift * Add test plan validation # Conflicts: # Tests/ProjectSpecTests/ProjectSpecTests.swift * Check for multiple default test plans * set first plan as default default plan * small tweaks * fix test plan path properties * add test plants to target scheme * docs * fix fixture test plan path * update changelog * added ability to disable test plan path validation Co-authored-by: Ota Mares --- CHANGELOG.md | 5 ++ Docs/ProjectSpec.md | 18 ++++++ Sources/ProjectSpec/FileType.swift | 1 + Sources/ProjectSpec/Project.swift | 1 + Sources/ProjectSpec/Scheme.swift | 33 +++++++++-- Sources/ProjectSpec/SpecOptions.swift | 1 + Sources/ProjectSpec/SpecValidation.swift | 16 ++++++ Sources/ProjectSpec/SpecValidationError.swift | 6 ++ Sources/ProjectSpec/Target.swift | 1 + Sources/ProjectSpec/TargetScheme.swift | 14 +++++ Sources/ProjectSpec/TestPlan.swift | 39 +++++++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 7 +++ Sources/XcodeGenKit/Version.swift | 4 +- .../Project.xcodeproj/project.pbxproj | 2 +- .../SPM/SPM.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/xcschemes/App.xcscheme | 2 +- .../AnotherProject.xcodeproj/project.pbxproj | 2 +- .../TestProject/App_iOS/App_iOS.xctestplan | 45 +++++++++++++++ .../Project.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/xcschemes/App_Clip.xcscheme | 2 +- .../xcschemes/App_Scheme.xcscheme | 8 ++- .../xcschemes/App_iOS Production.xcscheme | 2 +- .../xcschemes/App_iOS Staging.xcscheme | 2 +- .../xcschemes/App_iOS Test.xcscheme | 2 +- .../xcshareddata/xcschemes/App_macOS.xcscheme | 2 +- .../xcschemes/App_watchOS.xcscheme | 2 +- .../xcschemes/DriverKitDriver.xcscheme | 2 +- .../EndpointSecuritySystemExtension.xcscheme | 2 +- .../xcshareddata/xcschemes/Framework.xcscheme | 2 +- .../xcschemes/NetworkSystemExtension.xcscheme | 2 +- .../xcshareddata/xcschemes/Tool.xcscheme | 2 +- .../xcschemes/iMessageApp.xcscheme | 2 +- .../xcschemes/iMessageExtension.xcscheme | 2 +- Tests/Fixtures/TestProject/project.yml | 2 + .../paths_test/included_paths_test.yml | 17 +++++- .../TestProject.xcodeproj/project.pbxproj | 2 +- Tests/ProjectSpecTests/ProjectSpecTests.swift | 57 +++++++++++++++++++ Tests/ProjectSpecTests/SpecLoadingTests.swift | 23 +++++++- .../SchemeGeneratorTests.swift | 27 +++++++++ 39 files changed, 335 insertions(+), 32 deletions(-) create mode 100644 Sources/ProjectSpec/TestPlan.swift create mode 100644 Tests/Fixtures/TestProject/App_iOS/App_iOS.xctestplan diff --git a/CHANGELOG.md b/CHANGELOG.md index 21fe20146..543740ebb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Next Version +Some support for Xcode Test Plans has been added. For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode + +#### Added +- Schemes and Target Schemes can now reference existing Test Plans under `{scheme}.test.testPlans` and `{target}.scheme.testPlans`, respectively. #716 @yonaskolb @omares + #### Fixed - Fixed an issue where DocC was not added to source file list #1202 @hiragram diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 936c2fa5f..85a3157ea 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -114,6 +114,7 @@ Note that target names can also be changed by adding a `name` property to a targ - [ ] **disabledValidations**: **[String]** - A list of validations that can be disabled if they're too strict for your use case. By default this is set to an empty array. Currently these are the available options: - `missingConfigs`: Disable errors for configurations in yaml files that don't exist in the project itself. This can be useful if you include the same yaml file in different projects - `missingConfigFiles`: Disable checking for the existence of configuration files. This can be useful for generating a project in a context where config files are not available. + - `missingTestPlans`: Disable checking if test plan paths exist. This can be useful if your test plans haven't been created yet. - [ ] **defaultConfig**: **String** - The default configuration for command line builds from Xcode. If the configuration provided here doesn't match one in your [configs](#configs) key, XcodeGen will fail. If you don't set this, the first configuration alphabetically will be chosen. - [ ] **groupSortPosition**: **String** - Where groups are sorted in relation to other files. Either: - `none` - sorted alphabetically with all the other files @@ -661,6 +662,7 @@ This is a convenience used to automatically generate schemes for a target based - [ ] **region**: **String** - a String that indicates the region used for running and testing. This defaults to nil - [ ] **commandLineArguments**: **[String:Bool]** - a dictionary from the argument name (`String`) to if it is enabled (`Bool`). These arguments will be added to the Test, Profile and Run scheme actions - [ ] **environmentVariables**: **[[Environment Variable](#environment-variable)]** or **[String:String]** - environment variables for Run, Test and Profile scheme actions. When passing a dictionary, every key-value entry maps to a corresponding variable that is enabled. +- [ ] **testPlans**: **[[Test Plan](#test-plan)]** - List of test plan locations that will be referenced in the scheme. - [ ] **preActions**: **[[Execution Action](#execution-action)]** - Scripts that are run *before* the build action - [ ] **postActions**: **[[Execution Action](#execution-action)]** - Scripts that are run *after* the build action - [ ] **storeKitConfiguration**: **String** - specify storekit configuration to use during run. See [Options](#options). @@ -833,6 +835,7 @@ A multiline script can be written using the various YAML multiline methods, for - [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file - [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true. - [ ] **deleteScreenshotsWhenEachTestSucceeds**: **Bool** - whether successful UI tests should cause automatically-captured screenshots to be deleted. If `captureScreenshotsAutomatically` is false, this value is ignored. This defaults to true. +- [ ] **testPlans**: **[[Test Plan](#test-plan)]** - List of test plan locations that will be referenced in the scheme. #### Test Target A target can be one of a 2 types: @@ -940,6 +943,21 @@ schemes: revealArchiveInOrganizer: false ``` +### Test Plan +For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode. + +- [x] **path**: **String** - path that provides the `xctestplan` location. +- [ ] **defaultPlan**: **Bool** - a bool that defines if given plan is the default one. Defaults to false. If no default is set on any test plan, the first plan is set as the default. + +```yaml +schemes: + TestTarget: + test: + testPlans: + - path: app.xctestplan + defaultPlan: true +``` + ## Scheme Template This is a template that can be referenced from a normal scheme using the `templates` property. The properties of this template are the same as a [Scheme](#scheme). This functions identically in practice to [Target Template](#target-template). diff --git a/Sources/ProjectSpec/FileType.swift b/Sources/ProjectSpec/FileType.swift index 9fa9729b9..70ae76321 100644 --- a/Sources/ProjectSpec/FileType.swift +++ b/Sources/ProjectSpec/FileType.swift @@ -114,5 +114,6 @@ extension FileType { "xcfilelist": FileType(buildPhase: BuildPhaseSpec.none), "apns": FileType(buildPhase: BuildPhaseSpec.none), "pch": FileType(buildPhase: BuildPhaseSpec.none), + "xctestplan": FileType(buildPhase: BuildPhaseSpec.none), ] } diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index f015d55f5..bc82e9aa5 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -230,6 +230,7 @@ extension Project: PathContainer { .object("targets", Target.pathProperties), .object("targetTemplates", Target.pathProperties), .object("aggregateTargets", AggregateTarget.pathProperties), + .object("schemes", Scheme.pathProperties), .object("projectReferences", ProjectReference.pathProperties), ] } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 73c762d62..00ffafd19 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -123,7 +123,7 @@ public struct Scheme: Equatable { public var macroExpansion: String? public init( - config: String, + config: String? = nil, executable: String? = nil, commandLineArguments: [String: Bool] = [:], preActions: [ExecutionAction] = [], @@ -182,6 +182,7 @@ public struct Scheme: Equatable { public var customLLDBInit: String? public var captureScreenshotsAutomatically: Bool public var deleteScreenshotsWhenEachTestSucceeds: Bool + public var testPlans: [TestPlan] public struct TestTarget: Equatable, ExpressibleByStringLiteral { @@ -231,7 +232,7 @@ public struct Scheme: Equatable { } public init( - config: String, + config: String? = nil, gatherCoverageData: Bool = gatherCoverageDataDefault, coverageTargets: [TestableTargetReference] = [], disableMainThreadChecker: Bool = disableMainThreadCheckerDefault, @@ -242,6 +243,7 @@ public struct Scheme: Equatable { preActions: [ExecutionAction] = [], postActions: [ExecutionAction] = [], environmentVariables: [XCScheme.EnvironmentVariable] = [], + testPlans: [TestPlan] = [], language: String? = nil, region: String? = nil, debugEnabled: Bool = debugEnabledDefault, @@ -258,6 +260,7 @@ public struct Scheme: Equatable { self.preActions = preActions self.postActions = postActions self.environmentVariables = environmentVariables + self.testPlans = testPlans self.language = language self.region = region self.debugEnabled = debugEnabled @@ -287,7 +290,7 @@ public struct Scheme: Equatable { public var askForAppToLaunch: Bool? public init( - config: String, + config: String? = nil, commandLineArguments: [String: Bool] = [:], preActions: [ExecutionAction] = [], postActions: [ExecutionAction] = [], @@ -316,7 +319,7 @@ public struct Scheme: Equatable { public var preActions: [ExecutionAction] public var postActions: [ExecutionAction] public init( - config: String, + config: String? = nil, customArchiveName: String? = nil, revealArchiveInOrganizer: Bool = revealArchiveInOrganizerDefault, preActions: [ExecutionAction] = [], @@ -341,6 +344,17 @@ public struct Scheme: Equatable { } } +extension Scheme: PathContainer { + + static var pathProperties: [PathProperty] { + [ + .dictionary([ + .object("test", Test.pathProperties), + ]), + ] + } +} + protocol BuildAction: Equatable { var config: String? { get } } @@ -460,6 +474,15 @@ extension Scheme.Run: JSONEncodable { } } +extension Scheme.Test: PathContainer { + + static var pathProperties: [PathProperty] { + [ + .object("testPlans", TestPlan.pathProperties), + ] + } +} + extension Scheme.Test: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -499,6 +522,7 @@ extension Scheme.Test: JSONObjectConvertible { preActions = jsonDictionary.json(atKeyPath: "preActions") ?? [] postActions = jsonDictionary.json(atKeyPath: "postActions") ?? [] environmentVariables = try XCScheme.EnvironmentVariable.parseAll(jsonDictionary: jsonDictionary) + testPlans = try (jsonDictionary.json(atKeyPath: "testPlans") ?? []).map { try TestPlan(jsonDictionary: $0) } language = jsonDictionary.json(atKeyPath: "language") region = jsonDictionary.json(atKeyPath: "region") debugEnabled = jsonDictionary.json(atKeyPath: "debugEnabled") ?? Scheme.Test.debugEnabledDefault @@ -516,6 +540,7 @@ extension Scheme.Test: JSONEncodable { "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, + "testPlans": testPlans.map { $0.toJSONValue() }, "config": config, "language": language, "region": region, diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index f70139ef7..a5df4e28d 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -41,6 +41,7 @@ public struct SpecOptions: Equatable { public enum ValidationType: String { case missingConfigs case missingConfigFiles + case missingTestPlans } public enum SettingPresets: String { diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index bf814ead4..c0141b100 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -126,6 +126,11 @@ extension Project { errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget.name)) } } + + if !options.disabledValidations.contains(.missingTestPlans) { + let invalidTestPlans: [TestPlan] = scheme.testPlans.filter { !(basePath + $0.path).exists } + errors.append(contentsOf: invalidTestPlans.map{ .invalidTestPlan($0) }) + } } for script in target.buildScripts { @@ -205,6 +210,17 @@ extension Project { if let action = scheme.run, let config = action.config, getConfig(config) == nil { errors.append(.invalidSchemeConfig(scheme: scheme.name, config: config)) } + + if !options.disabledValidations.contains(.missingTestPlans) { + let invalidTestPlans: [TestPlan] = scheme.test?.testPlans.filter { !(basePath + $0.path).exists } ?? [] + errors.append(contentsOf: invalidTestPlans.map{ .invalidTestPlan($0) }) + } + + let defaultPlanCount = scheme.test?.testPlans.filter { $0.defaultPlan }.count ?? 0 + if (defaultPlanCount > 1) { + errors.append(.multipleDefaultTestPlans) + } + if let action = scheme.test, let config = action.config, getConfig(config) == nil { errors.append(.invalidSchemeConfig(scheme: scheme.name, config: config)) } diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index f4025bbf8..2cbf04473 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -33,6 +33,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidPerConfigSettings case invalidProjectReference(scheme: String, reference: String) case invalidProjectReferencePath(ProjectReference) + case invalidTestPlan(TestPlan) + case multipleDefaultTestPlans public var description: String { switch self { @@ -82,6 +84,10 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Scheme \(scheme.quoted) has invalid project reference \(project.quoted)" case let .invalidProjectReferencePath(reference): return "Project reference \(reference.name) has a project file path that doesn't exist \"\(reference.path)\"" + case let .invalidTestPlan(testPlan): + return "Test plan path \"\(testPlan.path)\" doesn't exist" + case .multipleDefaultTestPlans: + return "Your test plans contain more than one default test plan" } } } diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index 60752f445..9736694ce 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -144,6 +144,7 @@ extension Target: PathContainer { .object("postCompileScripts", BuildScript.pathProperties), .object("postBuildScripts", BuildScript.pathProperties), .object("legacy", LegacyTarget.pathProperties), + .object("scheme", TargetScheme.pathProperties), ]), ] } diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 9eb7f2792..59818a070 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -22,9 +22,11 @@ public struct TargetScheme: Equatable { public var environmentVariables: [XCScheme.EnvironmentVariable] public var preActions: [Scheme.ExecutionAction] public var postActions: [Scheme.ExecutionAction] + public var testPlans: [TestPlan] public init( testTargets: [Scheme.Test.TestTarget] = [], + testPlans: [TestPlan] = [], configVariants: [String] = [], gatherCoverageData: Bool = gatherCoverageDataDefault, coverageTargets: [TestableTargetReference] = [], @@ -40,6 +42,7 @@ public struct TargetScheme: Equatable { postActions: [Scheme.ExecutionAction] = [] ) { self.testTargets = testTargets + self.testPlans = testPlans self.configVariants = configVariants self.gatherCoverageData = gatherCoverageData self.coverageTargets = coverageTargets @@ -89,6 +92,7 @@ extension TargetScheme: JSONObjectConvertible { coverageTargets = [] } + testPlans = try (jsonDictionary.json(atKeyPath: "testPlans") ?? []).map { try TestPlan(jsonDictionary: $0) } configVariants = jsonDictionary.json(atKeyPath: "configVariants") ?? [] gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? TargetScheme.gatherCoverageDataDefault storeKitConfiguration = jsonDictionary.json(atKeyPath: "storeKitConfiguration") @@ -111,6 +115,7 @@ extension TargetScheme: JSONEncodable { "coverageTargets": coverageTargets.map { $0.reference }, "commandLineArguments": commandLineArguments, "testTargets": testTargets.map { $0.toJSONValue() }, + "testPlans": testPlans.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, @@ -147,3 +152,12 @@ extension TargetScheme: JSONEncodable { return dict } } + +extension TargetScheme: PathContainer { + + static var pathProperties: [PathProperty] { + [ + .object("testPlans", TestPlan.pathProperties), + ] + } +} diff --git a/Sources/ProjectSpec/TestPlan.swift b/Sources/ProjectSpec/TestPlan.swift new file mode 100644 index 000000000..c3ebf0d49 --- /dev/null +++ b/Sources/ProjectSpec/TestPlan.swift @@ -0,0 +1,39 @@ +import Foundation +import JSONUtilities + +public struct TestPlan: Equatable { + public var path: String + public var defaultPlan: Bool + + public init(path: String, defaultPlan: Bool = false) { + self.defaultPlan = defaultPlan + self.path = path + } +} + + +extension TestPlan: JSONObjectConvertible { + + public init(jsonDictionary: JSONDictionary) throws { + path = try jsonDictionary.json(atKeyPath: "path") + defaultPlan = jsonDictionary.json(atKeyPath: "defaultPlan") ?? false + } +} + +extension TestPlan: JSONEncodable { + public func toJSONValue() -> Any { + [ + "path": path, + "defaultPlan": defaultPlan, + ] + } +} + +extension TestPlan: PathContainer { + + static var pathProperties: [PathProperty] { + [ + .string("path"), + ] + } +} diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index b96077243..60922f29e 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -245,10 +245,16 @@ public class SchemeGenerator { let launchVariables = scheme.run.flatMap { $0.environmentVariables.isEmpty ? nil : $0.environmentVariables } let profileVariables = scheme.profile.flatMap { $0.environmentVariables.isEmpty ? nil : $0.environmentVariables } + let defaultTestPlanIndex = scheme.test?.testPlans.firstIndex { $0.defaultPlan } ?? 0 + let testPlans = scheme.test?.testPlans.enumerated().map { index, testPlan in + XCScheme.TestPlanReference(reference: "container:\(testPlan.path)", default: defaultTestPlanIndex == index) + } ?? [] + let testAction = XCScheme.TestAction( buildConfiguration: scheme.test?.config ?? defaultDebugConfig.name, macroExpansion: buildableReference, testables: testables, + testPlans: testPlans.isEmpty ? nil : testPlans, preActions: scheme.test?.preActions.map(getExecutionAction) ?? [], postActions: scheme.test?.postActions.map(getExecutionAction) ?? [], selectedDebuggerIdentifier: (scheme.test?.debugEnabled ?? Scheme.Test.debugEnabledDefault) ? XCScheme.defaultDebugger : "", @@ -439,6 +445,7 @@ extension Scheme { commandLineArguments: targetScheme.commandLineArguments, targets: targetScheme.testTargets, environmentVariables: targetScheme.environmentVariables, + testPlans: targetScheme.testPlans, language: targetScheme.language, region: targetScheme.region ), diff --git a/Sources/XcodeGenKit/Version.swift b/Sources/XcodeGenKit/Version.swift index f94d42e26..fe1b24af8 100644 --- a/Sources/XcodeGenKit/Version.swift +++ b/Sources/XcodeGenKit/Version.swift @@ -8,11 +8,11 @@ extension Project { } var schemeVersion: String { - "1.3" + "1.7" } var compatibilityVersion: String { - "Xcode 10.0" + "Xcode 11.0" } var objectVersion: UInt { diff --git a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj index 1c1440059..b99951bd2 100644 --- a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj @@ -317,7 +317,7 @@ }; }; buildConfigurationList = D91E14E36EC0B415578456F2 /* Build configuration list for PBXProject "Project" */; - compatibilityVersion = "Xcode 10.0"; + compatibilityVersion = "Xcode 11.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj index 234e31cfe..9efdbfe4f 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ 2DA7998902987953B119E4CE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F7EFEE613987D1E1258A60 /* AppDelegate.swift */; }; 3986ED6965842721C46C0452 /* SwiftRoaringDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */; }; 4CC663B42B270404EF5FD037 /* libStaticLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */; }; - 578E78BC3627CF48FB2CE129 /* App.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = A9601593D0AD02931266A4E5 /* App.xctestplan */; }; 9AD886A88D3E4A1B5E900687 /* SPMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7970A2253B14A9B27C307FAC /* SPMTests.swift */; }; 9C4AD0711D706FD3ED0E436D /* StaticLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */; }; B89EA0F3859878A1DCF7BAFD /* SwiftRoaringDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -204,7 +203,7 @@ }; }; buildConfigurationList = 425866ADA259DB93FC4AF1E3 /* Build configuration list for PBXProject "SPM" */; - compatibilityVersion = "Xcode 10.0"; + compatibilityVersion = "Xcode 11.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -231,7 +230,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 578E78BC3627CF48FB2CE129 /* App.xctestplan in Resources */, E368431019ABC696E4FFC0CF /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme index ff4048c2f..a1a2a212e 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> + version = "1.7"> + version = "1.7"> + + + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme index 479690500..36f91c749 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> + version = "1.7"> Date: Tue, 10 May 2022 15:03:39 +1000 Subject: [PATCH 39/55] update xcodeproj (#1213) --- CHANGELOG.md | 5 +++++ Package.resolved | 4 ++-- Package.swift | 2 +- Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 543740ebb..4a693bfff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,17 @@ Some support for Xcode Test Plans has been added. For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode #### Added + - Schemes and Target Schemes can now reference existing Test Plans under `{scheme}.test.testPlans` and `{target}.scheme.testPlans`, respectively. #716 @yonaskolb @omares #### Fixed - Fixed an issue where DocC was not added to source file list #1202 @hiragram +#### Changed + +- Updated XcodeProj to 8.7.1 #1213 @yonaskolb + ## 2.28.0 #### Added diff --git a/Package.resolved b/Package.resolved index e883890e9..613d2c8f0 100644 --- a/Package.resolved +++ b/Package.resolved @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/tuist/XcodeProj.git", "state": { "branch": null, - "revision": "aa2a42c7a744ca18b5918771fdd6cf40f9753db5", - "version": "8.6.0" + "revision": "c75c3acc25460195cfd203a04dde165395bf00e0", + "version": "8.7.1" } }, { diff --git a/Package.swift b/Package.swift index c1d72975f..bbdef9595 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.9.2"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.6.0"), + .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.7.0"), .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.3"), .package(url: "https://github.com/mxcl/Version", from: "2.0.0"), .package(url: "https://github.com/SwiftDocOrg/GraphViz.git", .exact("0.2.0")), diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 8ff7142d0..cc3fa31dc 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -766,7 +766,7 @@ B198242976C3395E31FE000A /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; }; B1C33BB070583BE3B0EC0E68 /* App_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; B221F5A689AD7D3AD52F56B8 /* libStaticLibrary_ObjC.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libStaticLibrary_ObjC.a; sourceTree = BUILT_PRODUCTS_DIR; }; - B5C943D39DD7812CAB94B614 /* Documentation.docc */ = {isa = PBXFileReference; path = Documentation.docc; sourceTree = ""; }; + B5C943D39DD7812CAB94B614 /* Documentation.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Documentation.docc; sourceTree = ""; }; B76E17CE3574081D5BF45B44 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; BA040F1F7D6CA08878323A55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; BB178D03E75929F3F5B10C56 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; From 29bcb9259136f04781ef5d736471f01357e43b04 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Tue, 10 May 2022 15:04:43 +1000 Subject: [PATCH 40/55] Update to 2.29.0 --- CHANGELOG.md | 2 ++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a693bfff..aa5408714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.29.0 + Some support for Xcode Test Plans has been added. For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode #### Added diff --git a/Makefile b/Makefile index 467033559..d5f6668c9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.28.0 +VERSION = 2.29.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 8966c4c0e..b8088cbeb 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.28.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.29.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index f64962f9e..e80d7965f 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.28.0") +let version = Version("2.29.0") let cli = XcodeGenCLI(version: version) cli.execute() From a2348d0cfa32427599ff3ec351b59709e3f65f5c Mon Sep 17 00:00:00 2001 From: Mark Turner Date: Wed, 15 Jun 2022 04:33:42 +0100 Subject: [PATCH 41/55] Example of vscode usage as a development environment (#1218) --- Docs/Examples.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Docs/Examples.md b/Docs/Examples.md index 27159d966..b2120985c 100644 --- a/Docs/Examples.md +++ b/Docs/Examples.md @@ -11,3 +11,4 @@ These are a bunch of real world examples of XcodeGen project specs. Feel free to - [minvws/nl-covid19-notification-app-ios](https://github.com/minvws/nl-covid19-notification-app-ios/blob/master/project.yml) - [pvinis/react-native-xcodegen](https://github.com/pvinis/react-native-xcodegen/blob/master/templates) - [covid19cz/erouska-ios](https://github.com/covid19cz/erouska-ios/blob/develop/project.yml) +- [markst/hotreloading-vscode-ios](https://github.com/markst/hotreloading-vscode-ios) From f65dad76252a876eae19ce72ea3649f95401e084 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Wed, 15 Jun 2022 23:54:28 -0400 Subject: [PATCH 42/55] Speed up SettingsBuilder (#1221) * Speed up SettingsBuilder It's unnecessary to build up a whole grouped dictionary only to check if all platforms are identical and then immediately discard the dictionary. Instead we can check if all targets match the first platform, which avoids creating a new dictionary but also allows bailing early as soon as a non-matching platform is found. Generating a large project (36MB json spec) on an M1 Max machine leads to a ~6% total speedup: 28.48s vs 30.07s. * Add changelog entry --- CHANGELOG.md | 4 ++++ Sources/XcodeGenKit/SettingsBuilder.swift | 12 +++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa5408714..b8200acb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Changed + +- Speed up generating build settings for large projects #1221 @jpsim + ## 2.29.0 Some support for Xcode Test Plans has been added. For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode diff --git a/Sources/XcodeGenKit/SettingsBuilder.swift b/Sources/XcodeGenKit/SettingsBuilder.swift index 4ac1853c3..36a252db9 100644 --- a/Sources/XcodeGenKit/SettingsBuilder.swift +++ b/Sources/XcodeGenKit/SettingsBuilder.swift @@ -11,12 +11,10 @@ extension Project { var buildSettings: BuildSettings = [:] // set project SDKROOT is a single platform - if targets.count > 0 { - let platforms = Dictionary(grouping: targets) { $0.platform } - if platforms.count == 1 { - let platform = platforms.first!.key - buildSettings["SDKROOT"] = platform.sdkRoot - } + if let firstPlatform = targets.first?.platform, + targets.allSatisfy({ $0.platform == firstPlatform }) + { + buildSettings["SDKROOT"] = firstPlatform.sdkRoot } if let type = config.type, options.settingPresets.applyProject { @@ -31,7 +29,7 @@ extension Project { } } - // Prevent setting presets from overrwriting settings in project xcconfig files + // Prevent setting presets from overwriting settings in project xcconfig files if let configPath = configFiles[config.name] { buildSettings = removeConfigFileSettings(from: buildSettings, configPath: configPath) } From 19817f319272cbb3cb5d20992a0289a733191b19 Mon Sep 17 00:00:00 2001 From: Luca Bartoletti Date: Sat, 16 Jul 2022 07:46:31 +0100 Subject: [PATCH 43/55] Fix `watchapp2-container` product name (#1219) The correct name is `application.watchapp2-container` --- Docs/ProjectSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 85a3157ea..d29087426 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -274,6 +274,7 @@ This will provide default build settings for a certain product type. It can be a - `application.messages` - `application.watchapp` - `application.watchapp2` +- `application.watchapp2-container` - `app-extension` - `app-extension.intents-service` - `app-extension.messages` @@ -289,7 +290,6 @@ This will provide default build settings for a certain product type. It can be a - `framework.static` - `tool` - `tv-app-extension` -- `watchapp2-container` - `watchkit-extension` - `watchkit2-extension` - `xcode-extension` From c082bc0c7cf0181907921c27df0f12da796c0fc1 Mon Sep 17 00:00:00 2001 From: Aleksei Sapitskii <45671572+aleksproger@users.noreply.github.com> Date: Sat, 16 Jul 2022 09:46:42 +0300 Subject: [PATCH 44/55] Fix XcodeGen building after XcodeProj update to 8.8.0 (#1228) * Fix XcodeGen building after XcodeProj update to 8.8.0 **Reason** - XcodeProj has been updated and has API breaking changes **Content** - Added new enum case handling in `Linkage` - Renamed the enum case name for `XCWorkspaceDataFileRef.init` * add new product type to docs * update changelog Co-authored-by: Yonas Kolb --- CHANGELOG.md | 7 ++++- Docs/ProjectSpec.md | 1 + Package.resolved | 4 +-- Package.swift | 2 +- Sources/ProjectSpec/Linkage.swift | 3 +- Sources/XcodeGenKit/ProjectGenerator.swift | 2 +- .../xcshareddata/xcschemes/App.xcscheme | 22 +++++++-------- .../xcshareddata/xcschemes/App_Clip.xcscheme | 22 +++++++-------- .../xcschemes/App_Scheme.xcscheme | 28 +++++++++---------- .../xcschemes/App_iOS Production.xcscheme | 26 ++++++++--------- .../xcschemes/App_iOS Staging.xcscheme | 26 ++++++++--------- .../xcschemes/App_iOS Test.xcscheme | 26 ++++++++--------- .../xcshareddata/xcschemes/App_macOS.xcscheme | 8 +++--- .../xcschemes/App_watchOS.xcscheme | 12 ++++---- .../xcschemes/DriverKitDriver.xcscheme | 8 +++--- .../EndpointSecuritySystemExtension.xcscheme | 8 +++--- .../xcshareddata/xcschemes/Framework.xcscheme | 8 +++--- .../xcschemes/NetworkSystemExtension.xcscheme | 8 +++--- .../xcshareddata/xcschemes/Tool.xcscheme | 8 +++--- .../xcschemes/iMessageApp.xcscheme | 8 +++--- .../xcschemes/iMessageExtension.xcscheme | 12 ++++---- 21 files changed, 128 insertions(+), 121 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8200acb7..473f529bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,15 @@ ## Next Version -### Changed +### Added +- Added support for new target type `extensionkit-extension` in Xcode 14 #1228 @aleksproger +### Changed - Speed up generating build settings for large projects #1221 @jpsim +### Fixed +- Fix XcodeGen building as library after breaking XcodeProj update 8.8.0 #1228 @aleksproger + ## 2.29.0 Some support for Xcode Test Plans has been added. For now test plans are not generated by XcodeGen and must be created in Xcode and checked in, and then referenced by path. If the test targets are added, removed or renamed, the test plans may need to be updated in Xcode diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index d29087426..93edda1c6 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -283,6 +283,7 @@ This will provide default build settings for a certain product type. It can be a - `bundle.ocunit-test` - `bundle.ui-testing` - `bundle.unit-test` +- `extensionkit-extension` - `framework` - `instruments-package` - `library.dynamic` diff --git a/Package.resolved b/Package.resolved index 613d2c8f0..509ec1c4d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/tuist/XcodeProj.git", "state": { "branch": null, - "revision": "c75c3acc25460195cfd203a04dde165395bf00e0", - "version": "8.7.1" + "revision": "b6de1bfe021b861c94e7c83821b595083f74b997", + "version": "8.8.0" } }, { diff --git a/Package.swift b/Package.swift index bbdef9595..9d709baf7 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "4.2.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.9.2"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.7.0"), + .package(url: "https://github.com/tuist/XcodeProj.git", from: "8.8.0"), .package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.3"), .package(url: "https://github.com/mxcl/Version", from: "2.0.0"), .package(url: "https://github.com/SwiftDocOrg/GraphViz.git", .exact("0.2.0")), diff --git a/Sources/ProjectSpec/Linkage.swift b/Sources/ProjectSpec/Linkage.swift index 0e134fa08..250f8207f 100644 --- a/Sources/ProjectSpec/Linkage.swift +++ b/Sources/ProjectSpec/Linkage.swift @@ -35,7 +35,8 @@ extension Target { .xcodeExtension, .xpcService, .systemExtension, - .driverExtension: + .driverExtension, + .extensionKitExtension: return .none case .framework, .xcFramework: // Check the MACH_O_TYPE for "Static Framework" diff --git a/Sources/XcodeGenKit/ProjectGenerator.swift b/Sources/XcodeGenKit/ProjectGenerator.swift index 65f3216ec..798b112f1 100644 --- a/Sources/XcodeGenKit/ProjectGenerator.swift +++ b/Sources/XcodeGenKit/ProjectGenerator.swift @@ -32,7 +32,7 @@ public class ProjectGenerator { } func generateWorkspace() throws -> XCWorkspace { - let selfReference = XCWorkspaceDataFileRef(location: .`self`("")) + let selfReference = XCWorkspaceDataFileRef(location: .current("")) let dataElement = XCWorkspaceDataElement.file(selfReference) let workspaceData = XCWorkspaceData(children: [dataElement]) return XCWorkspace(data: workspaceData) diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme index a1a2a212e..8e271576f 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -27,8 +27,17 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + + + @@ -51,15 +60,6 @@ - - - - diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Clip.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Clip.xcscheme index 5634a004d..a82515872 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Clip.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Clip.xcscheme @@ -27,8 +27,17 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + + + @@ -51,15 +60,6 @@ - - - - diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme index c157cfbed..b4e470e1b 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_Scheme.xcscheme @@ -27,16 +27,25 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "NO" + customLLDBInitFile = "${SRCROOT}/.lldbinit" shouldUseLaunchSchemeArgsEnv = "YES" - customLLDBInitFile = "${SRCROOT}/.lldbinit"> + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + + + @@ -65,15 +74,6 @@ - - - - @@ -81,13 +81,13 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "${SRCROOT}/.lldbinit" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES" - customLLDBInitFile = "${SRCROOT}/.lldbinit"> + allowLocationSimulation = "YES"> + disableMainThreadChecker = "YES" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + @@ -53,15 +62,6 @@ - - - - diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Staging.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Staging.xcscheme index ca647df98..d68715c4c 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Staging.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Staging.xcscheme @@ -27,10 +27,19 @@ buildConfiguration = "Staging Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES" shouldUseLaunchSchemeArgsEnv = "NO" - disableMainThreadChecker = "YES"> + disableMainThreadChecker = "YES" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + @@ -53,15 +62,6 @@ - - - - diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Test.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Test.xcscheme index cef83f897..38d23c89b 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Test.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Test.xcscheme @@ -27,10 +27,19 @@ buildConfiguration = "Test Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES" shouldUseLaunchSchemeArgsEnv = "NO" - disableMainThreadChecker = "YES"> + disableMainThreadChecker = "YES" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + @@ -53,15 +62,6 @@ - - - - diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_macOS.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_macOS.xcscheme index 094f19bb0..b4c58b615 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_macOS.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_macOS.xcscheme @@ -27,10 +27,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_watchOS.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_watchOS.xcscheme index 3282fb2af..63ec7f6a8 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_watchOS.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_watchOS.xcscheme @@ -41,10 +41,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + @@ -68,8 +68,8 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES"> + runnableDebuggingMode = "2" + BundleIdentifier = "com.apple.Carousel"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/EndpointSecuritySystemExtension.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/EndpointSecuritySystemExtension.xcscheme index 9657adfa5..be2f3dab4 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/EndpointSecuritySystemExtension.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/EndpointSecuritySystemExtension.xcscheme @@ -27,10 +27,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme index af66ac90f..d2be18573 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme @@ -46,12 +46,10 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" language = "ja" + shouldUseLaunchSchemeArgsEnv = "YES" region = "en" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/NetworkSystemExtension.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/NetworkSystemExtension.xcscheme index 960e22426..81af9fc04 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/NetworkSystemExtension.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/NetworkSystemExtension.xcscheme @@ -27,10 +27,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Tool.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Tool.xcscheme index bdde4cd53..4eea0b5b4 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Tool.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Tool.xcscheme @@ -27,10 +27,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageApp.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageApp.xcscheme index 064fffc40..30a5fccf5 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageApp.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageApp.xcscheme @@ -27,10 +27,8 @@ buildConfiguration = "Production Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - onlyGenerateCoverageForSpecifiedTargets = "NO" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageExtension.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageExtension.xcscheme index ed530e2c9..5a9e872ba 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageExtension.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/iMessageExtension.xcscheme @@ -1,8 +1,8 @@ + wasCreatedForAppExtension = "YES" + version = "1.7"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO"> + + From c1d5c65ae48e70f7424cc2084904a688c0236d5d Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sat, 16 Jul 2022 16:57:26 +1000 Subject: [PATCH 45/55] Update to 2.30.0 --- CHANGELOG.md | 2 ++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 473f529bc..924fe6c80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.30.0 + ### Added - Added support for new target type `extensionkit-extension` in Xcode 14 #1228 @aleksproger diff --git a/Makefile b/Makefile index d5f6668c9..95dd937ba 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.29.0 +VERSION = 2.30.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index b8088cbeb..742132d09 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.29.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.30.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index e80d7965f..9560bb756 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.29.0") +let version = Version("2.30.0") let cli = XcodeGenCLI(version: version) cli.execute() From da8aad004fab67da0ea3a126dc9791a65665bc36 Mon Sep 17 00:00:00 2001 From: matsuji Date: Thu, 21 Jul 2022 20:25:34 +0900 Subject: [PATCH 46/55] Add a new CopyFilesBuildPhase, "Embed ExtensionKit Extensions" (#1230) * Embed ExtensionKit Extensions * Fix explicitFileType for extensionKit * Update ChangeLog * Fix if statement structure * Add a new example extension to Tests/Fixtures/TestProject/ * Update Tests/Fixtures/TestProject/Project.xcodeproj * Comment out example for extension kit extension in Tests/Fixtures/TestProject/ * Update Tests/Fixtures/TestProject/Project.xcodeproj --- CHANGELOG.md | 2 + Sources/XcodeGenKit/PBXProjGenerator.swift | 24 +++++++--- Sources/XcodeGenKit/XCProjExtensions.swift | 6 ++- .../ExtensionKit Extension/EntryPoint.swift | 5 +++ .../ExtensionKit Extension/Info.plist | 11 +++++ .../ExtensionKit Extension/Intent.swift | 9 ++++ Tests/Fixtures/TestProject/project.yml | 9 ++++ .../ProjectGeneratorTests.swift | 44 +++++++++++++++++++ 8 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 Tests/Fixtures/TestProject/ExtensionKit Extension/EntryPoint.swift create mode 100644 Tests/Fixtures/TestProject/ExtensionKit Extension/Info.plist create mode 100644 Tests/Fixtures/TestProject/ExtensionKit Extension/Intent.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 924fe6c80..9beb6e1cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Change Log ## Next Version +### Added +- Added a new CopyFilesBuildPhase, "Embed ExtensionKit Extensions" #1230 @mtj0928 ## 2.30.0 diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 20ffcfb0e..60ebdfca3 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -128,8 +128,8 @@ public class PBXProjGenerator { var explicitFileType: String? var lastKnownFileType: String? - let fileType = Xcode.fileType(path: Path(target.filename)) - if target.platform == .macOS || target.platform == .watchOS || target.type == .framework { + let fileType = Xcode.fileType(path: Path(target.filename), productType: target.type) + if target.platform == .macOS || target.platform == .watchOS || target.type == .framework || target.type == .extensionKitExtension { explicitFileType = fileType } else { lastKnownFileType = fileType @@ -670,6 +670,7 @@ public class PBXProjGenerator { var copyWatchReferences: [PBXBuildFile] = [] var packageDependencies: [XCSwiftPackageProductDependency] = [] var extensions: [PBXBuildFile] = [] + var extensionKitExtensions: [PBXBuildFile] = [] var systemExtensions: [PBXBuildFile] = [] var appClips: [PBXBuildFile] = [] var carthageFrameworksToEmbed: [String] = [] @@ -736,8 +737,13 @@ public class PBXProjGenerator { // custom copy takes precedence customCopyDependenciesReferences.append(embedFile) } else if dependencyTarget.type.isExtension { - // embed app extension - extensions.append(embedFile) + if dependencyTarget.type == .extensionKitExtension { + // embed extension kit extension + extensionKitExtensions.append(embedFile) + } else { + // embed app extension + extensions.append(embedFile) + } } else if dependencyTarget.type.isSystemExtension { // embed system extension systemExtensions.append(embedFile) @@ -1156,13 +1162,21 @@ public class PBXProjGenerator { if !extensions.isEmpty { - let copyFilesPhase = addObject( + let copyFilesPhase = addObject( getPBXCopyFilesBuildPhase(dstSubfolderSpec: .plugins, name: "Embed App Extensions", files: extensions) ) buildPhases.append(copyFilesPhase) } + if !extensionKitExtensions.isEmpty { + + let copyFilesPhase = addObject( + getPBXCopyFilesBuildPhase(dstSubfolderSpec: .productsDirectory, dstPath: "$(EXTENSIONS_FOLDER_PATH)", name: "Embed ExtensionKit Extensions", files: extensionKitExtensions) + ) + buildPhases.append(copyFilesPhase) + } + if !systemExtensions.isEmpty { let copyFilesPhase = addObject( diff --git a/Sources/XcodeGenKit/XCProjExtensions.swift b/Sources/XcodeGenKit/XCProjExtensions.swift index dc03fe9d5..4247ce910 100644 --- a/Sources/XcodeGenKit/XCProjExtensions.swift +++ b/Sources/XcodeGenKit/XCProjExtensions.swift @@ -53,10 +53,12 @@ extension Dictionary { extension Xcode { - public static func fileType(path: Path) -> String? { + public static func fileType(path: Path, productType: PBXProductType? = nil) -> String? { guard let fileExtension = path.extension else { return nil } - switch fileExtension { + switch (fileExtension, productType) { // cases that aren't handled (yet) in XcodeProj. + case ("appex", .extensionKitExtension): + return "wrapper.extensionkit-extension" default: // fallback to XcodeProj defaults return Xcode.filetype(extension: fileExtension) diff --git a/Tests/Fixtures/TestProject/ExtensionKit Extension/EntryPoint.swift b/Tests/Fixtures/TestProject/ExtensionKit Extension/EntryPoint.swift new file mode 100644 index 000000000..0e665c55f --- /dev/null +++ b/Tests/Fixtures/TestProject/ExtensionKit Extension/EntryPoint.swift @@ -0,0 +1,5 @@ +import AppIntents + +@main +struct EntryPoint: AppIntentsExtension { +} diff --git a/Tests/Fixtures/TestProject/ExtensionKit Extension/Info.plist b/Tests/Fixtures/TestProject/ExtensionKit Extension/Info.plist new file mode 100644 index 000000000..8d15acbed --- /dev/null +++ b/Tests/Fixtures/TestProject/ExtensionKit Extension/Info.plist @@ -0,0 +1,11 @@ + + + + + EXAppExtensionAttributes + + EXExtensionPointIdentifier + com.apple.appintents-extension + + + diff --git a/Tests/Fixtures/TestProject/ExtensionKit Extension/Intent.swift b/Tests/Fixtures/TestProject/ExtensionKit Extension/Intent.swift new file mode 100644 index 000000000..0449c505c --- /dev/null +++ b/Tests/Fixtures/TestProject/ExtensionKit Extension/Intent.swift @@ -0,0 +1,9 @@ +import AppIntents + +struct Intent: AppIntent { + static var title: LocalizedStringResource = "Intent" + + func perform() async throws -> some IntentResult { + return .result() + } +} diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 5692e7e2c..7b6d4ea59 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -146,6 +146,9 @@ targets: - package: Swinject product: Swinject platformFilter: iOS +# https://github.com/yonaskolb/XcodeGen/issues/1232 +# After GitHub Actions start supporting Xcode 14, an example for extensionKit should be added. +# - target: ExtensionKitExtension onlyCopyFilesOnInstall: true scheme: testTargets: @@ -390,6 +393,12 @@ targets: sources: App_Clip_UITests dependencies: - target: App_Clip +# https://github.com/yonaskolb/XcodeGen/issues/1232 +# After GitHub Actions start supporting Xcode 14, an example for extensionKit should be added. +# ExtensionKitExtension: +# type: extensionkit-extension +# platform: iOS +# sources: ExtensionKit Extension schemes: Framework: diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 168bf4017..4ed5ae082 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -2094,6 +2094,50 @@ class ProjectGeneratorTests: XCTestCase { try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .executables, dstPath: "test") } } + + $0.context("extensionKit") { + + let extA = Target( + name: "extA", + type: .extensionKitExtension, + platform: .macOS + ) + let extB = Target( + name: "extB", + type: .extensionKitExtension, + platform: .macOS + ) + + $0.it("embeds them into plugins without copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true), + Dependency(type: .target, reference: extB.name, embed: false), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .productsDirectory, dstPath: "$(EXTENSIONS_FOLDER_PATH)") + } + + $0.it("embeds them into custom location with copy phase spec") { + + // given + let dependencies = [ + Dependency(type: .target, reference: extA.name, embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .productsDirectory, subpath: "test", phaseOrder: .postCompile)), + Dependency(type: .target, reference: extB.name, embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .productsDirectory, subpath: "test", phaseOrder: .postCompile)), + ] + + // when + let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [extA, extB]) + + // then + try expectCopyPhase(in: pbxProject, withFilePaths: ["extA.appex"], toSubFolder: .productsDirectory, dstPath: "test") + } + } $0.context("commandLineTool") { From 24572daeb5daac32b68a68e4cc4ec301151ea73b Mon Sep 17 00:00:00 2001 From: Aleksei Sapitskii <45671572+aleksproger@users.noreply.github.com> Date: Sun, 24 Jul 2022 09:08:33 +0300 Subject: [PATCH 47/55] Added duplicate dependencies validation (#1234) **Reason** - More strict validation of added dependencies **Contents** - Added changelog entry - Added check for duplicates in validation stage - Added test --- CHANGELOG.md | 163 +++++++++++++++++- Sources/ProjectSpec/Dependency.swift | 2 +- Sources/ProjectSpec/SpecValidation.swift | 80 +++++---- Sources/ProjectSpec/SpecValidationError.swift | 3 + Tests/ProjectSpecTests/ProjectSpecTests.swift | 34 ++++ 5 files changed, 241 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9beb6e1cc..05019a753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,24 @@ # Change Log ## Next Version + ### Added + - Added a new CopyFilesBuildPhase, "Embed ExtensionKit Extensions" #1230 @mtj0928 +- Added duplicate dependencies validation #1234 @aleksproger ## 2.30.0 ### Added + - Added support for new target type `extensionkit-extension` in Xcode 14 #1228 @aleksproger ### Changed + - Speed up generating build settings for large projects #1221 @jpsim ### Fixed + - Fix XcodeGen building as library after breaking XcodeProj update 8.8.0 #1228 @aleksproger ## 2.29.0 @@ -35,7 +41,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen #### Added -- Support for specifying custom group locations for SPM packages. #1173 @John-Connolly +- Support for specifying custom group locations for SPM packages. #1173 @John-Connolly ### Fixed @@ -67,11 +73,12 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ### Changed -- Speed up source inclusion checking for big projects #1122 @PaulTaykalo +- Speed up source inclusion checking for big projects #1122 @PaulTaykalo ## 2.25.0 ### Added + - Allow specifying a `copy` setting for each dependency. #1038 @JakubBednar ### Fixed @@ -95,50 +102,61 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Add ability to specify UI testing screenshot behavior in test schemes #942 @daltonclaybrook ### Changed + - **Breaking**: Rename the `platform` field on `Dependency` to `platformFilter` #1087 @daltonclaybrook ## 2.23.1 ### Changed + - Reverted "Change FRAMEWORK_SEARCH_PATH for xcframeworks (#1015)", introduced in 2.20.0. XCFrameworks need to be referenced directly in the project for Xcode's build system to extract the appropriate frameworks #1081 @elliottwilliams ## 2.23.0 #### Added + - Added ability to set custom platform for dependency #934 @raptorxcz #### Fixed + - Added `()` to config variant trimming charater set to fix scheme config variant lookups for some configs like `Debug (Development)` that broke in 2.22.0 #1078 @DavidWoohyunLee - Fixed Linux builds on Swift 5.4 #1083 @yonaskolb ## 2.22.0 #### Added + - Support `runPostActionsOnFailure` for running build post scripts on failing build #1075 @freddi-kit #### Changed + - Xcode no longer alerts to project changes after regeneration, due to internal workspace not regenerating if identical #1072 @yonaskolb #### Fixed + - Fixed no such module `DOT` error when package is used as a dependency #1067 @yanamura - Fixed scheme config variant lookups for some configs like `ProdDebug` and `Prod-Debug` that broke in 2.21.0 #1070 @yonaskolb ## 2.21.0 #### Added + - Support weak link for Swift Package Dependency #1064 @freddi-kit #### Changed + - Carthage frameworks are no longer embedded for "order-only" target dependencies. This avoid redundant embeds in situations where a target's sources _import_ a Carthage framework but do not have a binary dependency on it (like a test target which runs in a host app). #1041 @elliottwilliams #### Fixed + - The `Core` target is renamed to avoid collisions with other packages. #1057 @elliottwilliams - Lookup scheme config variants by whole words, fixing incorrect assignment in names that contain subtrings of each other (eg PreProd and Prod) #976 @stefanomondino ## 2.20.0 #### Added + - Allow specifying a `github` name like `JohnSundell/Ink` instead of a full `url` for Swift Packages #1029 @yonaskolb - Added explicity `LastUpgradeCheck` and `LastUpgradeVersion` override support so it's possible to override these properties without using the `project.xcodeVersion`. [1013](https://github.com/yonaskolb/XcodeGen/pull/1013) @Andre113 - Added `macroExpansion` for `run` in `schemes` #1036 @freddi-kit @@ -146,17 +164,20 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added support for selectedTests in schemes `Test` configuration. #913 @ooodin #### Fixed + - Fixed regression on `.storekit` configuration files' default build phase. #1026 @jcolicchio - Fixed framework search paths when using `.xcframework`s. #1015 @FranzBusch - Fixed bug where schemes without a build target would crash instead of displaying an error #1040 @dalemyers - Fixed files with names ending in **Info.plist** (such as **GoogleServices-Info.plist**) from being omitted from the Copy Resources build phase. Now, only the resolved info plist file for each specific target is omitted. #1027 @liamnichols #### Internal + - Build universal binaries for release. XcodeGen now runs natively on Apple Silicon. #1024 @thii ## 2.19.0 #### Added + - Added support for building and running on Linux platforms. Tested for compatibility with Swift 5.3+ and Ubuntu 18.04. #988 @elliottwilliams - Added `useBaseInternationalization` to Project Spec Options to opt out of Base Internationalization. #961 @liamnichols - Added `storeKitConfiguration` to allow specifying StoreKit Configuration in Scheme and TargetScheme, supporting either xcodeproj or xcworkspace via `schemePathPrefix` option. #964 @jcolicchio @@ -166,22 +187,26 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added discovered dependency file for a build script #1012 @polac24 @fggeraissate #### Changed + - **Breaking**: Info.plists with custom prefixes are no longer added to the Copy Bundle Resources build phase #945 @anivaros - **Breaking**: `workingDirectory` of included legacy targets is now made relative to including project #981 @jcolicchio - **Breaking**: Make `simulateLocation` respect `schemePathPrefix` option. #973 @jcolicchio #### Fixed + - Fixed error message output for `minimumXcodeGenVersion`. #967 @joshwalker - Remove force-unwrapping causing crash for `LegacyTarget`s #982 @jcolicchio - Fixed a race condition in an internal JSON decoder, which would occasionally fail with an error like `Parsing project spec failed: Error Domain=Unspecified error Code=0`. #995 @elliottwilliams - Fixed issue where frameworks with `MACH_O_TYPE: staticlib` were being incorrectly embedded. #1003 @mrabiciu #### Internal + - Updated to Yams 4.0.0 #984 @swiftty ## 2.18.0 #### Added + - Add `Scheme.Test.TestTarget.skipped` to allow skipping of an entire test target. #916 @codeman9 - Added ability to set custom LLDBInit scripts for launch and test schemes #929 @polac24 - Adds App Clip support. #909 @brentleyjones @dflems @@ -190,12 +215,15 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Enable Base Internationalization by default as per Xcode 12 behavior. #954 @liamnichols #### Changed + - Change default project version to Xcode 12 #960 @yonaskolb #### Internal + - Updates CI to run on Xcode 12. #936 @dflems @yonaskolb #### Fixed + - Select the first runnable build target, if present. #957 @codeman9 - Allow SDK dependencies to be embedded. #922 @k-thorat - Allow creating intermediary groups outside of the project directory. #892 @segiddins @@ -205,21 +233,25 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.17.0 #### Added + - Added `options.fileTypes` which lets you set cross project defaults for certain file extensions #914 @yonaskolb - Added `onlyCopyFilesOnInstall` option to targets for the Embed Files build phase. #912 @jsorge #### Fixed + - Treat all directories with known UTI as file wrapper. #896 @KhaosT - Generated schemes for application extensions now contain `wasCreatedForAppExtension = YES`. #898 @muizidn - Allow package dependencies to use `link: false` #920 @k-thorat - Fixed issue computing relative paths. #915 @andrewreach #### Internal + - Updated to XcodeProj 7.13.0 #908 @brentleyjones ## 2.16.0 #### Added + - Improve speed of metadata parsing and dependency resolution. #803 @michaeleisel - Improve support for iOS sticker packs and add support for `launchAutomaticallySubstyle` to run schemes. #824 @scelis - Add --project-root option to generate command. #828 @ileitch @@ -230,6 +262,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added ability to set executable to Ask to Launch. #871 @pinda #### Fixed + - Fixed issue when linking and embeding static frameworks: they should be linked and NOT embed. #820 @acecilia - Fixed issue when generating projects for paths with a dot in the folder for swift sources. #826 @asifmohd - Prefix static library target filenames with 'lib' to match Xcode. #831 @ileitch @@ -251,6 +284,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.15.1 #### Fixed + - Fixed issue which caused watch app schemes to be generated incorrectly, preventing these apps from launching. #798 @daltonclaybrook - Added build presets for the target type `framework.static`. #819 @acecilia - Fixed XcodeProj resolution and updated to 7.10.0 #822 @soffes @@ -258,10 +292,12 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.15.0 #### Added + - Add support for local Swift Packages in `packages` using `path`. #808 @freddi-kit - Add `buildImplicitDependencies` as an option on `TargetScheme`. #810 @evandcoleman #### Fixed + - Fixed resolving path to local Swift Packages #796 @freddi-kit - Added ability to stop on every main thread checker issue on Run schemes and TargetSchemes #799 @ionutivan - Avoid copying ObjC interface header when SWIFT_INSTALL_OBJC_HEADER=false. #805 @kateinoigakukun @@ -269,9 +305,11 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.14.0 #### Added + - Add ability to embed and code sign Swift package dependencies with dynamic products. #788 @alexruperez #### Fixed + - Revert "Add Base to known regions even if one doesn't exist" #791 @bryansum - Set `defaultConfigurationName` for every target which is defined in a project. #787 @ken0nek - Set `TEST_TARGET_NAME` only when a project has UITest bundle. #792 @ken0nek @@ -280,30 +318,36 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.13.1 #### Fixed + - Validate scheme test action and test coverage target references before generating. #775 @liamnichols - Fixed parsing prerelease identifiers in Swift package versions #779 @yonaskolb - Fixed using legacy targets as dependencies #778 @yonaskolb #### Internal + - Updated to XcodeProj 7.8.0 #777 @yonaskolb -- Use https://github.com/mxcl/Version #779 @yonaskolb +- Use #779 @yonaskolb ## 2.13.0 #### Added + - Support External Target References via subprojects. #701 @evandcoleman #### Fixed + - Fixed compilation as library by locking down XcodeProj version #767 @yonaskolb - Stabilized sorting of groups with duplicate names/paths. #671 @ChristopherRogers - Moved `Copy Bundle Resources` to after `Link with Libraries` build phase #768 @yonaskolb #### Internal + - Updated to XcodeProj 7.7.0 #767 @yonaskolb ## 2.12.0 #### Added + - Added pre and post command options. Useful for running `pod install` in combination with `--use-cache` #759 @yonaskolb - Support for language and region settings on a target basis #728 @FranzBusch - Added option to generate only Info.plist files with `--only-plists` #739 @namolnad @@ -311,6 +355,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Support for On Demand Resources tags #753 @sipao #### Fixed + - Fixed resolving a relative path for `projectReference.path` #740 @kateinoigakukun - Don't add framework dependency's directory to `FRAMEWORK_SEARCH_PATHS` if it is implicit #744 @ikesyo @yutailang0119 - Fixed resolving relative path passed to `XcodeProj` #751 @PycKamil @@ -318,11 +363,13 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added an extra check for package versions. #755 @basvankuijck #### Internal + - Update to SwiftCLI 6.0 and use the new property wrappers #749 @yonaskolb ## 2.11.0 #### Added + - Add Carthage static framework dependencies support. #688 @giginet - Added `xcodegen dump` command #710 @yonaskolb - Added `--no-env` option to disable environment variables expansion #704 @rcari @@ -330,6 +377,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added new dependency type, `bundle`. This allows targets to copy bundles from other projects #616 @bsmith11 #### Fixed + - Improved variable expansion runtime #704 @rcari - Fixed missing headers for static framework targets #705 @wag-miles - Using more file types from XcodeProj for PBXFileReferences resulting in less project diffs #715 @yonaskolb @@ -338,6 +386,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Fixed unnecessary dependencies related to SwiftPM #726 @tid-kijyun #### Changed + - Deprecated `$old_form` variables in favor of `${new_form}` variables #704 @rcari - Updated XcodeProj to 7.4.0 #709 @yonaskolb - Updated to Swift 5.1 #714 @yonaskolb @@ -345,6 +394,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.10.1 #### Fixed + - Add Base to knownRegions even if one doesn't exist #694 @bryansum - Fixed missing `onlyGenerateCoverageForSpecifiedTargets` issue #700 @kateinoigakukun - Fixed regression on dependencies `link` flag #703 @rcari @@ -352,10 +402,12 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.10.0 #### Added + - Support Target Reference to another project. #655 @kateinoigakukun - Added `coverageTargets` for test target. This enables to gather code coverage for specific targets. #656 @kateinoigakukun #### Fixed + - Add base localisation by default even if no base localised files were found. Fixes warning in Xcode 11 #685 @yonaskolb - Don't generate CFBundleExecutable in default generated Info.plist for `bundle` target types #689 @FranzBusch - Fixed resolving relative paths with custom project destination #681 @giginet @@ -363,26 +415,31 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Fixed macOS unit test target TEST_HOST #696 @mjarvis #### Internal + - Restructure targets #698 @yonaskolb ## 2.9.0 #### Added + - Added Scheme Templates #672 @bclymer #### Fixed + - Fixed macOS unit test setting preset #665 @yonaskolb - Add `rcproject` files to sources build phase instead of resources #669 @Qusic - Prefer default configuration names for generated schemes #673 @giginet - Fixed some resource files being placed to "Recovered References" group #679 @nivanchikov #### Internal + - Updated to SwiftCLI 5.3.2 #667 @giginet - Fixed tests in case-sensitive file system #670 @Qusic ## 2.8.0 #### Added + - Added support for Swift Package dependencies #624 @yonaskolb - Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. #637 @bclymer - Support `dylib` SDK. #650 @kateinoigakukun @@ -390,74 +447,89 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added `debugEnabled` option for `run` and `test` scheme #657 @kateinoigakukun #### Fixed + - Expand template variable in Array of Any #651 @kateinoigakukun - Significantly improve performance when running with a large number files. #658 @kateinoigakukun - Removed some more diffs between the generated .pbxproj and when Xcode resaves it #663 @yonaskolb #### Internal + - Removed needless `Array` initialization. #661 @RomanPodymov - Updated to XcodeProj 7.1.0 #624 @yonaskolb ## 2.7.0 #### Added + - Added Bash 4 style recursive globbing (`**/*`) in target sources `excludes` #636 @bclymer - Added ability to disable main thread checker in Schemes #601 @wag-miles #### Fixed + - Fixed included specs that were referenced multiple times from duplicating content #599 @haritowa - Fixed `.orig` files being added to the project #627 @keith #### Changed + - Allow linking of dependencies into static libraries when `link` is set to true #635 @kateinoigakukun ## 2.6.0 #### Added + - Added ability to skip tests #582 @kadarandras - Added ability to set `attributes` on build files #583 @min - Allow using environment variables in the form of `${SOME_VARIABLE}`. This might be a **breaking** change when a target template attribute is also defined as an environment variable #594 @tomquist - Added support for `watchapp2-container` and `framework.static` product types #604 @yonaskolb #### Fixed + - Fixed `.pch` files being bundled as resources #597 @thii - Fixed an issue that prevents watchOS Intents Extension from running correctly. #571 @KhaosT #### Changed + - Updated the default `compatibilityVersion` project setting from `Xcode 9.3` to `Xcode 10.0` #581 @acecilia - Updated to XcodeProj 7.0.0. Note that the length of generated UUIDs has changed #604 @yonaskolb #### Internal + - Added ability to encode ProjectSpec #545 @ryohey ## 2.5.0 #### Added + - Added support for `app-extension.intents-service` target type #536 @yonaskolb - Added support for custom `root` in `sdk` dependency #562 @raptorxcz #### Changed + - Updated to xcodeproj 6.7.0 including its performance improvements #536 @yonaskolb - Updated default generated settings for Xcode 10.2 #555 @yonaskolb - Changed order of file generation so that plists are now generated before the project, so they will be included in the projects files #544 @tomquist - Updated Yams to 2.0.0 @yonaskolb #### Fixed + - Fixed groups from sources outside a project spec's directory from being flattened. #550 @sroebert - Fixed `optional` file sources not being added to the project #557 @yonaskolb - Fixed Carthage dependencies being incorrectly embedded in WatchKit app bundles instead of a WatchKit app extension #558 @KhaosT ## 2.4.0 -#### Fixed: +#### Fixed + - Fixed installation when building in Swift 5 #549 @yonaskolb #### Changed + - Updated to Swift 5 and dropped Swift 4.2 #549 @yonaskolb ## 2.3.0 #### Added + - Added ability to automatically find all the frameworks for Carthage dependencies via the global `options.findCarthageFrameworks` or dependency specfic `dependency.findFrameworks`. See the [Carthage](Docs/Usage.md#carthage) usage docs for more info #506 @rpassis @yonaskolb - Added support for nested target templates #534 @tomquist - Added ability to define `templateAttributes` within a target to be able to parameterize templates. #533 @tomquist @@ -466,9 +538,11 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added ability to define a per-platform `deploymentTarget` for Multi-Platform targets. #510 @ainopara #### Changed + - **DEPRECATION**: Placeholders `$target_name` and `$platform` have been deprecated in favour of `${target_name}` and `${platform}`. Support for the old placeholders will be removed in a future version #533 @tomquist #### Fixed + - Sources outside a project spec's directory will be correctly referenced as relative paths in the project file. #524 - Fixed error when `optional` directory source is missing #527 @yonaskolb - Fixed excludes within included spec #535 @yonaskolb @@ -479,6 +553,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.2.0 #### Added + - Added ability to generate empty directories via `options.generateEmptyDirectories` #480 @Beniamiiin - Added support for the `instrumentsPackage` product type #482 @ksulliva - Added support for `inputFileLists` and `outputFileLists` within project build scripts #500 @lukewakeford @@ -486,12 +561,14 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added `createIntermediateGroups` to individual Target Sources which overrides the top level option #505 @yonaskolb #### Changed + - **BREAKING**: All the paths within `include` files are now relative to that file and not the root spec. This can be disabled with a `relativePaths: false` on the include. See the [documentation](https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md#include) for more details #489 @ellneal - Updated the Xcode compatibility version from 3.2 to 9.3 #497 @yonaskolb - Exact matches to config names in build settings won't partial apply to other configs #503 @yonaskolb - UUIDs in the project are standard and don't contain any type prefixes anymore #### Fixed + - Fixed `--project` argument not taking effect #487 @monowerker - Fixed Sticker Packs from generating an empty Source file phase which caused in error in the new build system #492 @rpassis - Fixed generated schemes for tool targets not setting the executable #496 @yonaskolb @@ -500,14 +577,17 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.1.0 #### Added + - Added an experiment new caching feature. Pass `--use-cache` to opt in. This will read and write from a cache file to prevent unnecessarily generating the project. Give it a try as it may become the default in a future release #412 @yonaskolb #### Changed + - Changed spelling of build phases to **preBuildPhase** and **postBuildPhase**. The older names are deprecated but still work [402](https://github.com/yonaskolb/XcodeGen/pull/402) @brentleyjones - Moved generation to a specific subcommand `xcodegen generate`. Simple `xcodegen` will continue to work for now #437 @yonaskolb - If `INFOPLIST_FILE` has been set on a target, then an `info` path won't ovewrite it #443 @feischl97 #### Fixed + - Fixed XPC Service package type in generated `Info.plist` #435 @alvarhansen - Fixed phase ordering for modulemap and static libary header Copy File phases. [402](https://github.com/yonaskolb/XcodeGen/pull/402) @brentleyjones - Fixed intermittent errors when running multiple `xcodegen`s concurrently #450 @bryansum @@ -520,6 +600,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen ## 2.0.0 #### Added + - Added `weak` linking setting for dependencies #411 @alvarhansen - Added `info` to targets for generating an `Info.plist` #415 @yonaskolb - Added `entitlements` to targets for generating an `.entitlement` file #415 @yonaskolb @@ -529,6 +610,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Automatically set project `SDKROOT` if there is only a single platform within the project #433 @yonaskolb #### Changed + - Performance improvements for large projects #388 @yonaskolb @kastiglione - Upgraded to xcodeproj 6 #388 @yonaskolb - Upgraded to Swift 4.2 #388 @yonaskolb @@ -537,6 +619,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen - Added ability to not link Carthage frameworks #432 @yonaskolb #### Fixed + - Fixed code signing issues #414 @yonaskolb - Fixed `TargetSource.headerVisibility` not being set in initializer #419 @jerrymarino - Fixed crash when using Xcode Legacy targets as dependencies #427 @dflems @@ -546,24 +629,28 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project will not be deterministic. This will be fixed in an upcoming release with an update to xcodeproj 6.0 #### Fixed + - Fixed release builds in Swift 4.2 #404 @pepibumur - Fixed default settings for macOS unit-tests #387 @frankdilo - Fixed Copy Headers phase ordering for Xcode 10 #401 @brentleyjones - Fixed generated schemes on aggregate targets #394 @vgorloff #### Changed + - Added `en` as default value for knownRegions #390 @Saik0s - Update `PathKit`, `Spectre`, `Yams` and `xcodeproj` dependencies ## 1.11.1 #### Fixed + - Fixed `FRAMEWORK_SEARCH_PATHS` for `framework` dependency paths with spaces #382 @brentleyjones - Fixed aggregate targets not being found with `transitivelyLinkDependencies` #383 @brentleyjones ## 1.11.0 #### Added + - Added `showEnvVars` to build scripts to disable printing the environment #351 @keith - Added `requiresObjCLinking` to `target` #354 @brentleyjones - Added `targetTemplates` #355 @yonaskolb @@ -574,6 +661,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Added `customArchiveName` and `revealArchiveInOrganizer` to `archive` #367 @sxua #### Fixed + - Sort files using localizedStandardCompare #341 @rohitpal440 - Use the latest `xcdatamodel` when sorted by version #341 @rohitpal440 - Fixed compiler flags being set on non source files in mixed build phase target sources #347 @brentleyjones @@ -584,6 +672,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Fixed `.metal` files being added to resources #380 @vgorloff #### Changed + - Improved linking for `static.library` targets #352 @brentleyjones - Changed default group sorting to be after files #356 @yonaskolb - Moved `Frameworks` and `Products` top level groups to bottom #356 @yonaskolb @@ -595,41 +684,49 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Copy files phases have descriptive names #360 @brentley #### Internal + - Moved brew formula to homebrew core - Added `CONTRIBUTING.md` ## 1.10.3 #### Fixed + - Fixed Mint installations finding `SettingPresets` #338 @yonaskolb ## 1.10.2 #### Changed + - Set `transitivelyLinkDependencies` to false by default ## 1.10.1 #### Fixed + - Fixed `transitivelyLinkDependencies` typo #332 @brentleyjones - Fixed framework target dependencies not being code signed by default #332 @yonaskolb #### Changed + - Code sign all dependencies by default except target executables #332 @yonaskolb ## 1.10.0 #### Added + - Added build rule support #306 @yonaskolb - Added support for frameworks in sources #308 @keith - Added ability to automatically embed transient dependencies. Controlled with `transitivelyLinkDependencies` #327 @brentleyjones #### Changed + - Upgraded to Swift 4.1 - Improved Carthage dependency lookup performance with many targets #298 @keith - By default don't CodeSignOnCopy `target` dependencies. This can still be controlled with `Dependency.codeSign` #324 @yonaskolb #### Fixed + - Fixed PBXBuildFile and PBXFileReference being incorrectly generated for Legacy targets #296 @sascha - Fixed required sources build phase not being generated if there are no sources #307 @yonaskolb - Fixed install script in binary release #303 @alvarhansen @@ -644,15 +741,18 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.9.0 #### Added + - Scheme pre and post actions can now be added to `target.scheme` #280 @yonaskolb - Individual files can now be added to `fileGroups` #293 @yonaskolb #### Changed + - Updated to `xcproj` 4.3.0 for Xcode 9.3 updates - Update default Xcode version to 9.3 including new settings #284 @LinusU - **Breaking for ProjectSpec library users** Changed `ProjectSpec` to `Project` and `ProjectSpec.Options` to `SpecOptions` #281 @jerrymarino #### Fixed + - Fixed manual build phase of `none` not being applied to folders #288 @yonaskolb - Quoted values now correctly get parsed as strings #282 @yonaskolb - Fixed adding a root source folder when `createIntermediateGroups` is on #291 @yonaskolb @@ -662,16 +762,19 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.8.0 #### Added + - Added Project `defaultConfig` #269 @keith - Added Target `attributes` #276 @yonaskolb - Automatically set `DevelopmentTeam` and `ProvisioningStyle` within `TargetAttributes` if relevant build settings are defined #277 @yonaskolb #### Fixed + - Fixed default `LD_RUNPATH_SEARCH_PATHS` for app extensions #272 @LinusU #### Internal + - Make `LegacyTarget` init public #264 @jerrymarino -- Upgrade to *xcproj* to 4.2.0, *Yams* to 0.6.0 and *PathKit* to 0.9.1 @yonaskolb +- Upgrade to _xcproj_ to 4.2.0, _Yams_ to 0.6.0 and _PathKit_ to 0.9.1 @yonaskolb ## 1.7.0 @@ -688,6 +791,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - Releases now include a pre-compiled binary and setting presets, including an install script #### Fixed + - Fixed Mint installation from reading setting presets #248 @yonaskolb - Fixed setting `buildPhase` on a `folder` source. This allows for a folder of header files #254 @toshi0383 - Carthage dependencies are not automatically embedded into test targets #256 @yonaskolb @@ -698,23 +802,27 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.6.0 #### Added + - Added scheme pre-actions and post-actions #231 @kastiglione - Added `options.disabledValidations` including `missingConfigs` to disable project validation errors #220 @keith - Generate UI Test Target Attributes #221 @anreitersimon #### Fixed + - Filter out duplicate source files #217 @allu22 - Fixed how `lastKnownFileType` and `explicitFileType` were generated across platforms #115 @toshi0383 - Removed a few cases of project diffs when opening the project in Xcode @yonaskolb - Fixed Swift not being embedded by default in watch apps @yonaskolb #### Changed + - Change arrays to strings in setting presets #218 @allu22 - Updated to xcproj 4.0 #227 ## 1.5.0 #### Added + - added support for `gatherCoverageData` flag in target schemes #170 @alexruperez - added support for `commandLineOptions` in target schemes #172 @rahul-malik - added Project spec as a SwiftPM library for reuse in other projects #164 @soffes @@ -732,6 +840,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - added `deploymentTarget` setting to project and target #205 @yonaskolb #### Changed + - huge performance improvements when writing the project file due to changes in xcproj - updated dependencies - minor logging changes @@ -742,6 +851,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - when specifying a `--spec` argument, the default for the `--project` path is now the directory containing the spec #211 @yonaskolb #### Fixed + - fixed shell scripts escaping quotes twice #186 @allu22 - fixed `createIntermediateGroups` when using a relative spec path #184 @kastiglione - fixed command line arguments for test and profile from being overridden #199 @vhbit @@ -752,6 +862,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.4.0 #### Added + - added `--version` flag #112 @mironal - added support for adding individual file sources #106 @bkase - added source compiler flag support #121 @bkase @@ -762,6 +873,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - added `ProjectSpec.options.developmentLanguage` #155 @yonaskolb #### Changed + - updated to xcproj 1.2.0 #113 @yonaskolb - build settings from presets will be removed if they are provided in `xcconfig` files #77 @toshi0383 - all files and groups are sorted by type and then alphabetically #144 @yonaskolb @@ -770,6 +882,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - make UUIDs more deterministic #154 @yonaskolb #### Fixed + - only add headers to frameworks and libraries #118 @ryohey - fixed localized files with the same name #126 @ryohey - fix intermediate sources #144 @yonaskolb @@ -780,6 +893,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - all localizations found are added to a projects known regions #157 @ryohey #### Internal + - refactoring - more tests - added release scripts @@ -787,11 +901,13 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.3.0 #### Added + - generate output files for Carthage copy-frameworks script #84 @mironal - added options.settingPreset to choose which setting presets get applied #100 @yonaskolb - added `link` option for target dependencies #109 @keith #### Changed + - updated to xcproj 0.4.1 #85 @enmiller - don't copy base settings if config type has been left out #100 @yonaskolb - generate localised files under a single variant group #70 @ryohey @@ -800,6 +916,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - other small internal changes @yonaskolb #### Fixed + - embed Carthage frameworks for macOS #82 @toshi0383 - fixed copying of watchOS app resources #96 @keith - automatically ignore more file types for a target's sources (entitlements, gpx, apns) #94 @keith @@ -812,16 +929,19 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.2.4 #### Fixed + - setting presets only apply `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES` to applications - don't add carthage dependency to `copy-frameworks` script if `embed: false` - sort group children on APFS #### Changed + - update to xcproj 0.3.0 ## 1.2.3 #### Fixed + - Fixed wrong carthage directory name reference for macOS #74 @toshi0383 - Removed unnecessary `carthage copy-frameworks` for macOS app target #76 @toshi0383 - Added some missing default settings for framework targets. `SKIP_INSTALL: YES` fixes archiving @@ -830,16 +950,18 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.2.2 #### Added + - automatically set `TEST_TARGET_NAME` on UI test targets if one of the dependencies is an application target #### Fixed + - set `DYLIB_INSTALL_NAME_BASE` to `@rpath` in framework target presets - fixed tvOS launch screen setting. `ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME` is now `LaunchImage` not `tvOS LaunchImage` - ## 1.2.0 #### Added + - `include` now supports a single string as well as a list - add support setting xcconfig files on a project with `configFiles` #64 - add `fileGroups` to project spec for adding groups of files that aren't target source files #64 @@ -849,6 +971,7 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil - add `mint` installation support #### Fixed + - fixed homebrew installation - fixed target xcconfig files not working via `configFiles` #64 - look for `INFOPLIST_FILE` setting in project and xcconfig files before adding it automatically. It was just looking in target settings before #64 @@ -857,107 +980,129 @@ If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project wil ## 1.1.0 #### Changed + - set project version to Xcode 9 - `LastUpgradeVersion` attribute to `0900` - set default Swift version to 4.0 - `SWIFT_VERSION` build setting to `4.0` ### 1.0.1 ### Fixed + - fixed incorrect default build script shell path - fixed install scripts ## 1.0.0 #### Added + - Swift 4 support #52 - Support for C and C++ files #48 by @antoniocasero - Xcode 9 default settings #### Fixed + - fixed empty string in YAML not being parsed properly #50 by @antoniocasero #### Changed + - updated to xcodeproj 0.1.2 #56 - **BREAKING**: changed target definitions from list to map #54 - ## 0.6.1 #### Added + - Ability to set PBXProject attributes #45 #### Changed + - Don't bother linking target frameworks for target dependencies. - Move code signing default settings from all iOS targets to iOS application targets, via Product + Platform setting preset files #46 ## 0.6.0 #### Added + - Allow a project spec to include other project specs #44 #### Changed + - Changed default spec path to `project.yml` - Changed default project directory to the current directory instead of the spec file's directory ## 0.5.1 #### Fixed + - Fix embedded framework dependencies - Add `CODE_SIGN_IDENTITY[sdk=iphoneos*]` back to iOS targets - Fix build scripts with "" generating invalid projects #43 ## 0.5.0 + #### Added + - Added multi platform targets #35 - Automatically generate platform specific `FRAMEWORK_SEARCH_PATHS` for Carthage dependencies #38 - Automatically find Info.plist and set `INFOPLIST_FILE` build setting if it doesn't exist on a target #40 - Add options for controlling embedding of dependencies #37 #### Fixed + - Fixed localized files not being added to a target's resources #### Changed + - Renamed Setting Presets to Setting Groups - Carthage group is now created under top level Frameworks group ## 0.4.0 ##### Added + - Homebrew support #16 by @pepibumur - Added `runOnlyWhenInstalling` to build scripts #32 - Added `carthageBuildPath` option #34 #### Fixed + - Fixed installations of XcodeGen not applying build setting presets for configs, products, and platforms, due to missing resources #### Changed -- Upgraded to https://github.com/swift-xcode/xcodeproj 0.1.1 #33 + +- Upgraded to 0.1.1 #33 ## 0.3.0 - Extensions and Scheme Tests #### Added + - Support for app extension dependencies, using the same `target: MyExtension` syntax #19 - Added test targets to generated target schemes via `Target.scheme.testTargets` #21 #### Changed + - Updated xcodeproj to 0.0.9 #### Fixed + - Fixed watch and messages apps not copying carthage dependencies #### Breaking changes + - Changed `Target.generatedSchemes` to `Target.scheme.configVariants` ## 0.2.0 - Build scripts #### Added + - Added Target build scripts with `Target.prebuildScripts` and `Target.postbuildScripts` #17 - Support for absolute paths in target sources, run script files, and config files - Add validation for incorrect `Target.configFiles` #### Fixed + - Fixed some project objects sometimes having duplicate ids ## 0.1.0 -First official release +First official release diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 2037bd444..1c01a8d8f 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -56,7 +56,7 @@ public struct Dependency: Equatable { public static let `default` = dynamic } - public enum DependencyType: Equatable { + public enum DependencyType: Hashable { case target case framework case carthage(findFrameworks: Bool?, linkType: CarthageLinkType) diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index c0141b100..376c0153f 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -154,38 +154,16 @@ extension Project { } for target in targets { + var uniqueDependencies = Set() + for dependency in target.dependencies { - switch dependency.type { - case .target: - let dependencyTargetReference = try TargetReference(dependency.reference) - - switch dependencyTargetReference.location { - case .local: - if getProjectTarget(dependency.reference) == nil { - errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference)) - } - case .project(let dependencyProjectName): - if getProjectReference(dependencyProjectName) == nil { - errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference)) - } - } - case .sdk: - let path = Path(dependency.reference) - if !dependency.reference.contains("/") { - switch path.extension { - case "framework"?, - "tbd"?, - "dylib"?: - break - default: - errors.append(.invalidSDKDependency(target: target.name, dependency: dependency.reference)) - } - } - case .package: - if packages[dependency.reference] == nil { - errors.append(.invalidSwiftPackage(name: dependency.reference, target: target.name)) - } - default: break + let dependencyValidationErrors = try validate(dependency, in: target) + errors.append(contentsOf: dependencyValidationErrors) + + if uniqueDependencies.contains(dependency) { + errors.append(.duplicateDependencies(target: target.name, dependencyReference: dependency.reference)) + } else { + uniqueDependencies.insert(dependency) } } @@ -252,6 +230,46 @@ extension Project { } } + // Returns error if the given dependency from target is invalid. + private func validate(_ dependency: Dependency, in target: Target) throws -> [SpecValidationError.ValidationError] { + var errors: [SpecValidationError.ValidationError] = [] + + switch dependency.type { + case .target: + let dependencyTargetReference = try TargetReference(dependency.reference) + + switch dependencyTargetReference.location { + case .local: + if getProjectTarget(dependency.reference) == nil { + errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference)) + } + case .project(let dependencyProjectName): + if getProjectReference(dependencyProjectName) == nil { + errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference)) + } + } + case .sdk: + let path = Path(dependency.reference) + if !dependency.reference.contains("/") { + switch path.extension { + case "framework"?, + "tbd"?, + "dylib"?: + break + default: + errors.append(.invalidSDKDependency(target: target.name, dependency: dependency.reference)) + } + } + case .package: + if packages[dependency.reference] == nil { + errors.append(.invalidSwiftPackage(name: dependency.reference, target: target.name)) + } + default: break + } + + return errors + } + /// Returns a descriptive error if the given target reference was invalid otherwise `nil`. private func validationError(for targetReference: TargetReference, in scheme: Scheme, action: String) -> SpecValidationError.ValidationError? { switch targetReference.location { diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index 2cbf04473..eadfca3b9 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -35,6 +35,7 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidProjectReferencePath(ProjectReference) case invalidTestPlan(TestPlan) case multipleDefaultTestPlans + case duplicateDependencies(target: String, dependencyReference: String) public var description: String { switch self { @@ -88,6 +89,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Test plan path \"\(testPlan.path)\" doesn't exist" case .multipleDefaultTestPlans: return "Your test plans contain more than one default test plan" + case let .duplicateDependencies(target, dependencyReference): + return "Target \(target.quoted) has the dependency \(dependencyReference.quoted) multiple times" } } } diff --git a/Tests/ProjectSpecTests/ProjectSpecTests.swift b/Tests/ProjectSpecTests/ProjectSpecTests.swift index 65f9398eb..4024d68a3 100644 --- a/Tests/ProjectSpecTests/ProjectSpecTests.swift +++ b/Tests/ProjectSpecTests/ProjectSpecTests.swift @@ -142,6 +142,40 @@ class ProjectSpecTests: XCTestCase { try expectValidationError(project, .invalidBuildSettingConfig("invalidSettingGroupConfig")) } + $0.it("fails with duplicate dependencies") { + var project = baseProject + project.targets = [ + Target( + name: "target1", + type: .application, + platform: .iOS, + settings: invalidSettings, + dependencies: [ + Dependency(type: .target, reference: "dependency1"), + Dependency(type: .target, reference: "dependency1"), + Dependency(type: .framework, reference: "dependency2"), + Dependency(type: .framework, reference: "dependency2"), + ] + ), + Target( + name: "target2", + type: .framework, + platform: .iOS, + settings: invalidSettings, + dependencies: [ + Dependency(type: .framework, reference: "dependency3"), + Dependency(type: .target, reference: "dependency3"), + Dependency(type: .target, reference: "dependency4"), + Dependency(type: .target, reference: "dependency4"), + ] + ) + ] + + try expectValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "dependency1")) + try expectValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "dependency2")) + try expectValidationError(project, .duplicateDependencies(target: "target2", dependencyReference: "dependency4")) + } + $0.it("allows non-existent configurations") { var project = baseProject project.options = SpecOptions(disabledValidations: [.missingConfigs]) From de2a537ab4b6a88ee160b05b3c165ba42196586c Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sun, 24 Jul 2022 16:10:15 +1000 Subject: [PATCH 48/55] Update to 2.31.0 --- CHANGELOG.md | 2 ++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05019a753..c0c7eea3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.31.0 + ### Added - Added a new CopyFilesBuildPhase, "Embed ExtensionKit Extensions" #1230 @mtj0928 diff --git a/Makefile b/Makefile index 95dd937ba..67a431638 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.30.0 +VERSION = 2.31.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 742132d09..71790bb2a 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.30.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.31.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index 9560bb756..c58aaf2ff 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.30.0") +let version = Version("2.31.0") let cli = XcodeGenCLI(version: version) cli.execute() From ff552f38802d8b33b820bb09ccc71b5e79899379 Mon Sep 17 00:00:00 2001 From: antonsergeev88 Date: Sun, 31 Jul 2022 11:33:20 +0300 Subject: [PATCH 49/55] Handle mlmodelc as a single unit (#1237) * Handle mlmodelc as a single unit * Add mlmodelc support in changelog --- CHANGELOG.md | 4 ++++ Sources/ProjectSpec/FileType.swift | 1 + Tests/XcodeGenKitTests/SourceGeneratorTests.swift | 2 ++ 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0c7eea3f..a568b1e06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Added + +- Add support for `mlmodelc` files #1236 @antonsergeev88 + ## 2.31.0 ### Added diff --git a/Sources/ProjectSpec/FileType.swift b/Sources/ProjectSpec/FileType.swift index 70ae76321..c794b64e2 100644 --- a/Sources/ProjectSpec/FileType.swift +++ b/Sources/ProjectSpec/FileType.swift @@ -87,6 +87,7 @@ extension FileType { "intentdefinition": FileType(buildPhase: .sources), "metal": FileType(buildPhase: .sources), "mlmodel": FileType(buildPhase: .sources), + "mlmodelc": FileType(buildPhase: .resources), "rcproject": FileType(buildPhase: .sources), "iig": FileType(buildPhase: .sources), "docc": FileType(buildPhase: .sources), diff --git a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift index e1121df7d..de033f509 100644 --- a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift @@ -589,6 +589,7 @@ class SourceGeneratorTests: XCTestCase { - file.xcassets - file.metal - file.mlmodel + - file.mlmodelc - Info.plist - Intent.intentdefinition - Configuration.storekit @@ -647,6 +648,7 @@ class SourceGeneratorTests: XCTestCase { try pbxProj.expectFile(paths: ["C", "Info.plist"], buildPhase: BuildPhaseSpec.none) try pbxProj.expectFile(paths: ["C", "file.metal"], buildPhase: .sources) try pbxProj.expectFile(paths: ["C", "file.mlmodel"], buildPhase: .sources) + try pbxProj.expectFile(paths: ["C", "file.mlmodelc"], buildPhase: .resources) try pbxProj.expectFile(paths: ["C", "Intent.intentdefinition"], buildPhase: .sources) try pbxProj.expectFile(paths: ["C", "Configuration.storekit"], buildPhase: .resources) try pbxProj.expectFile(paths: ["C", "Settings.bundle"], buildPhase: .resources) From 34f50d645e6a3b0d9930c2b105c00521bfe2c8cf Mon Sep 17 00:00:00 2001 From: Isaac Halvorson Date: Mon, 1 Aug 2022 17:27:14 -0500 Subject: [PATCH 50/55] Correct name of package in example yaml (#1240) Hey there, I just noticed that one of the example yaml snippets had the wrong package name specified. --- Docs/ProjectSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 93edda1c6..ec9fba852 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -1019,7 +1019,7 @@ packages: Yams: url: https://github.com/jpsim/Yams from: 2.0.0 - Yams: + Ink: github: JohnSundell/Ink from: 0.5.0 RxClient: From ac525a445e0a1420fbe56248e18f1f0d9826b1af Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 9 Aug 2022 22:32:33 +0800 Subject: [PATCH 51/55] remove redundant bracket (#1243) --- Docs/ProjectSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index ec9fba852..41741ee7a 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -729,7 +729,7 @@ This is used to override settings or run build scripts in specific targets ## Target Template -This is a template that can be referenced from a normal target using the `templates` property. The properties of this template are the same as a [Target](#target)]. +This is a template that can be referenced from a normal target using the `templates` property. The properties of this template are the same as a [Target](#target). Any instances of `${target_name}` within each template will be replaced by the final target name which references the template. Any attributes defined within a targets `templateAttributes` will be used to replace any attribute references in the template using the syntax `${attribute_name}`. From e9295f1ff3284facb103e8a4dbb025f5246d5327 Mon Sep 17 00:00:00 2001 From: Steven Sheldon Date: Thu, 11 Aug 2022 05:45:06 -0700 Subject: [PATCH 52/55] Fix profile action to not run frameworks (#1245) * Fix profile action to not run frameworks * Add PR number to changelog * Update CHANGELOG.md Co-authored-by: Yonas Kolb --- CHANGELOG.md | 4 ++++ Sources/XcodeGenKit/SchemeGenerator.swift | 3 ++- .../xcshareddata/xcschemes/Framework.xcscheme | 5 ++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a568b1e06..2d903f2ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Add support for `mlmodelc` files #1236 @antonsergeev88 +### Fixed + +- Fix profile action for frameworks in Xcode 14 #1245 @SSheldon + ## 2.31.0 ### Added diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index 60922f29e..d188c11aa 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -320,10 +320,11 @@ public class SchemeGenerator { ) let profileAction = XCScheme.ProfileAction( - buildableProductRunnable: runnables.profile, + buildableProductRunnable: shouldExecuteOnLaunch ? runnables.profile : nil, buildConfiguration: scheme.profile?.config ?? defaultReleaseConfig.name, preActions: scheme.profile?.preActions.map(getExecutionAction) ?? [], postActions: scheme.profile?.postActions.map(getExecutionAction) ?? [], + macroExpansion: shouldExecuteOnLaunch ? nil : buildableReference, shouldUseLaunchSchemeArgsEnv: scheme.profile?.shouldUseLaunchSchemeArgsEnv ?? true, askForAppToLaunch: scheme.profile?.askForAppToLaunch, commandlineArguments: profileCommandLineArgs, diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme index d2be18573..3f0af839d 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme @@ -100,8 +100,7 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - + - + From 594c67fbe9df46d8e898be3e51ac02aae8fca853 Mon Sep 17 00:00:00 2001 From: "freddi(Yuki Aki)" Date: Fri, 12 Aug 2022 15:21:43 +0900 Subject: [PATCH 53/55] Add `enable` option for `include` to enable optional including for addtional spec (#1242) * add new option enable for include of spec * fix to see the environment variable when parsing include * add test for include with environment variable * fix how to parse boolean value * add spec about enable for include * add Change Log * fix the number of PR in changelog * fix include test to make more clear * fix test to focus enable option more * fix english error * fix to expand variable only one time * add new test case by setting environment object as NO --- CHANGELOG.md | 4 ++ Docs/ProjectSpec.md | 3 +- Sources/ProjectSpec/SpecFile.swift | 38 ++++++++++++------- Sources/ProjectSpec/SpecLoader.swift | 4 +- Tests/Fixtures/include_test.yml | 11 +++++- Tests/Fixtures/included_addtional.yml | 12 ++++++ Tests/PerformanceTests/PerformanceTests.swift | 4 +- Tests/ProjectSpecTests/SpecLoadingTests.swift | 36 +++++++++++++++++- 8 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 Tests/Fixtures/included_addtional.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d903f2ed..64892bce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ ### Added - Add support for `mlmodelc` files #1236 @antonsergeev88 +- Add `enable` option for `include` #1242 @freddi-kit + +### Fixed +- Fix checking environment variable in `include` #1242 @freddi-kit ### Fixed diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 41741ee7a..209655886 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -64,12 +64,13 @@ An include can be provided via a string (the path) or an object of the form: - [x] **path**: **String** - The path to the included file. - [ ] **relativePaths**: **Bool** - Dictates whether the included spec specifies paths relative to itself (the default) or the root spec file. - +- [ ] **enable**: **Bool** - Dictates whether the specified spec should be included or not. You can also specify it by environment variable. ```yaml include: - includedFile.yml - path: path/to/includedFile.yml relativePaths: false + enable: ${INCLUDE_ADDITIONAL_YAML} ``` By default specs are merged additively. That is for every value: diff --git a/Sources/ProjectSpec/SpecFile.swift b/Sources/ProjectSpec/SpecFile.swift index adf974711..6a1c59b43 100644 --- a/Sources/ProjectSpec/SpecFile.swift +++ b/Sources/ProjectSpec/SpecFile.swift @@ -1,6 +1,7 @@ import Foundation import JSONUtilities import PathKit +import Yams public struct SpecFile { public let basePath: Path @@ -13,17 +14,20 @@ public struct SpecFile { fileprivate struct Include { let path: Path let relativePaths: Bool + let enable: Bool static let defaultRelativePaths = true + static let defaultEnable = true init?(any: Any) { if let string = any as? String { path = Path(string) relativePaths = Include.defaultRelativePaths - } else if let dictionary = any as? JSONDictionary, - let path = dictionary["path"] as? String { + enable = Include.defaultEnable + } else if let dictionary = any as? JSONDictionary, let path = dictionary["path"] as? String { self.path = Path(path) - relativePaths = dictionary["relativePaths"] as? Bool ?? Include.defaultRelativePaths + relativePaths = Self.resolveBoolean(dictionary, key: "relativePaths") ?? Include.defaultRelativePaths + enable = Self.resolveBoolean(dictionary, key: "enable") ?? Include.defaultEnable } else { return nil } @@ -38,10 +42,14 @@ public struct SpecFile { return [] } } + + private static func resolveBoolean(_ dictionary: [String: Any], key: String) -> Bool? { + dictionary[key] as? Bool ?? (dictionary[key] as? NSString)?.boolValue + } } - public init(path: Path) throws { - try self.init(filePath: path, basePath: path.parent()) + public init(path: Path, variables: [String: String] = [:]) throws { + try self.init(filePath: path, basePath: path.parent(), variables: variables) } public init(filePath: Path, jsonDictionary: JSONDictionary, basePath: Path = "", relativePath: Path = "", subSpecs: [SpecFile] = []) { @@ -52,21 +60,23 @@ public struct SpecFile { self.filePath = filePath } - private init(include: Include, basePath: Path, relativePath: Path) throws { + private init(include: Include, basePath: Path, relativePath: Path, variables: [String: String]) throws { let basePath = include.relativePaths ? (basePath + relativePath) : (basePath + relativePath + include.path.parent()) let relativePath = include.relativePaths ? include.path.parent() : Path() - try self.init(filePath: include.path, basePath: basePath, relativePath: relativePath) + try self.init(filePath: include.path, basePath: basePath, variables: variables, relativePath: relativePath) } - private init(filePath: Path, basePath: Path, relativePath: Path = "") throws { + private init(filePath: Path, basePath: Path, variables: [String: String], relativePath: Path = "") throws { let path = basePath + relativePath + filePath.lastComponent - let jsonDictionary = try SpecFile.loadDictionary(path: path) + let jsonDictionary = try SpecFile.loadDictionary(path: path).expand(variables: variables) let includes = Include.parse(json: jsonDictionary["include"]) - let subSpecs: [SpecFile] = try includes.map { include in - try SpecFile(include: include, basePath: basePath, relativePath: relativePath) - } + let subSpecs: [SpecFile] = try includes + .filter(\.enable) + .map { include in + try SpecFile(include: include, basePath: basePath, relativePath: relativePath, variables: variables) + } self.init(filePath: filePath, jsonDictionary: jsonDictionary, basePath: basePath, relativePath: relativePath, subSpecs: subSpecs) } @@ -85,8 +95,8 @@ public struct SpecFile { } } - public func resolvedDictionary(variables: [String: String] = [:]) -> JSONDictionary { - resolvedDictionaryWithUniqueTargets().expand(variables: variables) + public func resolvedDictionary() -> JSONDictionary { + resolvedDictionaryWithUniqueTargets() } private func resolvedDictionaryWithUniqueTargets() -> JSONDictionary { diff --git a/Sources/ProjectSpec/SpecLoader.swift b/Sources/ProjectSpec/SpecLoader.swift index 142d3bf1d..d4493891a 100644 --- a/Sources/ProjectSpec/SpecLoader.swift +++ b/Sources/ProjectSpec/SpecLoader.swift @@ -16,8 +16,8 @@ public class SpecLoader { } public func loadProject(path: Path, projectRoot: Path? = nil, variables: [String: String] = [:]) throws -> Project { - let spec = try SpecFile(path: path) - let resolvedDictionary = spec.resolvedDictionary(variables: variables) + let spec = try SpecFile(path: path, variables: variables) + let resolvedDictionary = spec.resolvedDictionary() let project = try Project(basePath: projectRoot ?? spec.basePath, jsonDictionary: resolvedDictionary) self.project = project diff --git a/Tests/Fixtures/include_test.yml b/Tests/Fixtures/include_test.yml index 6affefa6d..1c24a731a 100644 --- a/Tests/Fixtures/include_test.yml +++ b/Tests/Fixtures/include_test.yml @@ -1,4 +1,11 @@ -include: [included.yml] +include: + - included.yml + - path: included_addtional.yml + enable: ${INCLUDE_ADDTIONAL_YAML} +packages: + Yams: + url: https://github.com/jpsim/Yams + majorVersion: 2.0.0 name: NewName settingGroups: test: @@ -19,3 +26,5 @@ targets: name: IncludedTargetNew platform: tvOS sources:REPLACE: NewSource + dependencies: + - package: Yams diff --git a/Tests/Fixtures/included_addtional.yml b/Tests/Fixtures/included_addtional.yml new file mode 100644 index 000000000..3623d2bea --- /dev/null +++ b/Tests/Fixtures/included_addtional.yml @@ -0,0 +1,12 @@ +name: Included_Addtional +settingGroups: + test: + MY_SETTING5: ADDTIONAL +packages: + SwiftPM: + url: https://github.com/apple/swift-package-manager + branch: swift-5.0-branch +targets: + IncludedTarget: + dependencies: + - package: SwiftPM diff --git a/Tests/PerformanceTests/PerformanceTests.swift b/Tests/PerformanceTests/PerformanceTests.swift index 294b1b9ce..6d2c5a2c4 100644 --- a/Tests/PerformanceTests/PerformanceTests.swift +++ b/Tests/PerformanceTests/PerformanceTests.swift @@ -15,8 +15,8 @@ class GeneratedPerformanceTests: XCTestCase { try dumpYamlDictionary(project.toJSONDictionary(), path: specPath) measure { - let spec = try! SpecFile(path: specPath) - _ = spec.resolvedDictionary(variables: ProcessInfo.processInfo.environment) + let spec = try! SpecFile(path: specPath, variables: ProcessInfo.processInfo.environment) + _ = spec.resolvedDictionary() } } diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift index 7bab9329d..0c9c96657 100644 --- a/Tests/ProjectSpecTests/SpecLoadingTests.swift +++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift @@ -29,7 +29,7 @@ class SpecLoadingTests: XCTestCase { describe { $0.it("merges includes") { let path = fixturePath + "include_test.yml" - let project = try loadSpec(path: path) + let project = try loadSpec(path: path, variables: [:]) try expect(project.name) == "NewName" try expect(project.settingGroups) == [ @@ -38,7 +38,39 @@ class SpecLoadingTests: XCTestCase { "toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]), ] try expect(project.targets) == [ - Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"]), + Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "Yams")]), + Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]), + ] + } + + $0.it("merges includes with addtional one") { + let path = fixturePath + "include_test.yml" + let project = try loadSpec(path: path, variables: ["INCLUDE_ADDTIONAL_YAML": "YES"]) + + try expect(project.name) == "NewName" + try expect(project.settingGroups) == [ + "test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}", "MY_SETTING5": "ADDTIONAL"]), + "new": Settings(dictionary: ["MY_SETTING": "VALUE"]), + "toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]), + ] + try expect(project.targets) == [ + Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "SwiftPM"), Dependency(type: .package(product: nil), reference: "Yams")]), + Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]), + ] + } + + $0.it("merges includes without addtional one by environemnt variable") { + let path = fixturePath + "include_test.yml" + let project = try loadSpec(path: path, variables: ["INCLUDE_ADDTIONAL_YAML": "NO"]) + + try expect(project.name) == "NewName" + try expect(project.settingGroups) == [ + "test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3", "MY_SETTING4": "${SETTING4}"]), + "new": Settings(dictionary: ["MY_SETTING": "VALUE"]), + "toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]), + ] + try expect(project.targets) == [ + Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "Yams")]), Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]), ] } From ebf70f1a718e90eeeefeebd02e1e0af1e9463f5a Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Fri, 19 Aug 2022 00:53:34 +1000 Subject: [PATCH 54/55] Update to 2.32.0 --- CHANGELOG.md | 6 +++--- Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64892bce3..168e7458e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,16 @@ ## Next Version +## 2.32.0 + ### Added - Add support for `mlmodelc` files #1236 @antonsergeev88 - Add `enable` option for `include` #1242 @freddi-kit -### Fixed -- Fix checking environment variable in `include` #1242 @freddi-kit - ### Fixed +- Fix checking environment variable in `include` #1242 @freddi-kit - Fix profile action for frameworks in Xcode 14 #1245 @SSheldon ## 2.31.0 diff --git a/Makefile b/Makefile index 67a431638..82db425cb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.31.0 +VERSION = 2.32.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 71790bb2a..befe058cf 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.31.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.32.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index c58aaf2ff..31f102bae 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.31.0") +let version = Version("2.32.0") let cli = XcodeGenCLI(version: version) cli.execute() From fe0017fc80ca531492d98d714e5006a89861ff89 Mon Sep 17 00:00:00 2001 From: Roland Heusser Date: Thu, 18 Aug 2022 19:31:52 -0600 Subject: [PATCH 55/55] update targets from "TargetReference" to "TestableTargetReference" --- Sources/XcodeGenKit/SpecGenerator.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/XcodeGenKit/SpecGenerator.swift b/Sources/XcodeGenKit/SpecGenerator.swift index 1aa955c79..cba964201 100644 --- a/Sources/XcodeGenKit/SpecGenerator.swift +++ b/Sources/XcodeGenKit/SpecGenerator.swift @@ -587,7 +587,7 @@ private extension Scheme { self.init( name: scheme.name, build: Scheme.Build( - targets: [BuildTarget(target: TargetReference(name: buildableReference.blueprintName, location: .local))], + targets: [BuildTarget(target: TestableTargetReference(name: buildableReference.blueprintName, location: .local))], parallelizeBuild: buildAction.parallelizeBuild, buildImplicitDependencies: buildAction.buildImplicitDependencies, preActions: buildAction.preActions.map(Scheme.ExecutionAction.init), @@ -617,7 +617,7 @@ private extension Scheme { test: scheme.testAction.flatMap { testAction in let targets = testAction.testables.map { Scheme.Test.TestTarget( - targetReference: TargetReference( + targetReference: TestableTargetReference( name: $0.buildableReference.blueprintName, location: .local), randomExecutionOrder: $0.parallelizable, @@ -630,7 +630,7 @@ private extension Scheme { config: testAction.buildConfiguration, gatherCoverageData: testAction.codeCoverageEnabled, coverageTargets: testAction.codeCoverageTargets.map { - TargetReference(name: $0.blueprintName, location: .local) + TestableTargetReference(name: $0.blueprintName, location: .local) }, disableMainThreadChecker: testAction.disableMainThreadChecker, randomExecutionOrder: targets.allSatisfy { $0.randomExecutionOrder },