From f51280485d7f836cefa99deb7136d407b5bad77c Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Tue, 24 Jul 2018 22:59:24 +1000 Subject: [PATCH] added options.groupSortPosition --- Docs/ProjectSpec.md | 4 ++++ Sources/ProjectSpec/SpecOptions.swift | 16 +++++++++++++- Sources/XcodeGenKit/PBXProjGenerator.swift | 22 +++++++++++++++++-- Sources/XcodeGenKit/XCProjExtensions.swift | 8 ------- .../Project.xcodeproj/project.pbxproj | 10 ++++----- Tests/Fixtures/TestProject/project.yml | 1 + 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 6f4210ad..10b712d9 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -87,6 +87,10 @@ 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 - [ ] **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: + - `top` - at the top, before files + - `bottom` - at the bottom, after other files + - `none` - sorted alphabetically with all the other files - [ ] **transitivelyLinkDependencies**: **Bool** - If this is `true` then targets will link to the dependencies of their target dependencies. If a target should embed its dependencies, such as application and test bundles, it will embed these transitive dependencies as well. Some complex setups might want to set this to `false` and explicitly specify dependencies at every level. Targets can override this with [Target](#target).transitivelyLinkDependencies. Defaults to `false`. ```yaml diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index f476575a..cd7bbf39 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -18,6 +18,7 @@ public struct SpecOptions: Equatable { public var deploymentTarget: DeploymentTarget public var defaultConfig: String? public var transitivelyLinkDependencies: Bool + public var groupSortPosition: GroupSortPosition public enum ValidationType: String { case missingConfigs @@ -44,6 +45,16 @@ public struct SpecOptions: Equatable { } } + /// Where groups are sorted in relation to other files + public enum GroupSortPosition: String { + /// groups are at the top + case top + /// groups are at the bottom + case bottom + /// groups are sorted with the rest of the files + case none + } + public init( carthageBuildPath: String? = nil, carthageExecutablePath: String? = nil, @@ -58,7 +69,8 @@ public struct SpecOptions: Equatable { deploymentTarget: DeploymentTarget = .init(), disabledValidations: [ValidationType] = [], defaultConfig: String? = nil, - transitivelyLinkDependencies: Bool = false + transitivelyLinkDependencies: Bool = false, + groupSortPosition: GroupSortPosition = .bottom ) { self.carthageBuildPath = carthageBuildPath self.carthageExecutablePath = carthageExecutablePath @@ -74,6 +86,7 @@ public struct SpecOptions: Equatable { self.disabledValidations = disabledValidations self.defaultConfig = defaultConfig self.transitivelyLinkDependencies = transitivelyLinkDependencies + self.groupSortPosition = groupSortPosition } } @@ -94,5 +107,6 @@ extension SpecOptions: JSONObjectConvertible { disabledValidations = jsonDictionary.json(atKeyPath: "disabledValidations") ?? [] defaultConfig = jsonDictionary.json(atKeyPath: "defaultConfig") transitivelyLinkDependencies = jsonDictionary.json(atKeyPath: "transitivelyLinkDependencies") ?? false + groupSortPosition = jsonDictionary.json(atKeyPath: "groupSortPosition") ?? .bottom } } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index b796d766..e6f44f52 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -395,10 +395,13 @@ public class PBXProjGenerator { return ObjectReference(reference: reference, object: fileElement) } .sorted { child1, child2 in - if child1.object.sortOrder == child2.object.sortOrder { + let sortOrder1 = child1.object.getSortOrder(groupSortPosition: project.options.groupSortPosition) + let sortOrder2 = child2.object.getSortOrder(groupSortPosition: project.options.groupSortPosition) + + if sortOrder1 == sortOrder2 { return child1.object.nameOrPath.localizedStandardCompare(child2.object.nameOrPath) == .orderedAscending } else { - return child1.object.sortOrder < child2.object.sortOrder + return sortOrder1 < sortOrder2 } } group.object.children = children.map { $0.reference }.filter { $0 != group.reference } @@ -875,3 +878,18 @@ extension Target { return type.isApp || type.isTest } } + +extension PBXFileElement { + + public func getSortOrder(groupSortPosition: SpecOptions.GroupSortPosition) -> Int { + if type(of: self).isa == "PBXGroup" { + switch groupSortPosition { + case .top: return -1 + case .bottom: return 1 + case .none: return 0 + } + } else { + return 0 + } + } +} diff --git a/Sources/XcodeGenKit/XCProjExtensions.swift b/Sources/XcodeGenKit/XCProjExtensions.swift index 22440387..edf9fe5e 100644 --- a/Sources/XcodeGenKit/XCProjExtensions.swift +++ b/Sources/XcodeGenKit/XCProjExtensions.swift @@ -6,14 +6,6 @@ extension PBXFileElement { public var nameOrPath: String { return name ?? path ?? "" } - - public var sortOrder: Int { - if type(of: self).isa == "PBXGroup" { - return 1 - } else { - return 0 - } - } } extension PBXProj { diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index e079486c..3df37908 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -551,11 +551,6 @@ G_8448771205358 = { isa = PBXGroup; children = ( - FR_479281060337 /* Folder */, - FR_815403394914 /* Headers */, - FR_232605427418 /* Mintfile */, - FR_257073931060 /* ResourceFolder */, - FR_775316160345 /* SomeFile */, G_8252321105004 /* App */, G_7831228999101 /* App_iOS_Tests */, G_1235039993875 /* App_iOS_UITests */, @@ -569,6 +564,11 @@ G_7189434949822 /* Resources */, G_6651250437419 /* StandaloneFiles */, G_3997550084026 /* StaticLibrary_ObjC */, + FR_479281060337 /* Folder */, + FR_815403394914 /* Headers */, + FR_232605427418 /* Mintfile */, + FR_257073931060 /* ResourceFolder */, + FR_775316160345 /* SomeFile */, G_1952740716080 /* Frameworks */, G_8620238527590 /* Products */, ); diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index f37b4f8c..bd85c939 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -8,6 +8,7 @@ options: transitivelyLinkDependencies: true deploymentTarget: watchOS: 4.0 + groupSortPosition: top fileGroups: - Configs - FileGroup