Skip to content

Commit

Permalink
Filter out empty auxiliary groups (#6142)
Browse files Browse the repository at this point in the history
Partially resolves: #6141

- #6057 introduced a `Cache` group to help distinguish cached artifacts from system libraries
- This didn't account for cases where the cache or cloud features aren't in use thus causing an additional `Cache` group to appear in all generated projects
- As a short term mitation we can filter out empty "auxiliary" groups at the end of the project generation steps
- This includes groups Xcode doesn't have by default including the `Frameworks` group which it only adds if a system library dependency is added

Notes:

- The `Product` group isn't treated as an auxiliary group as Xcode always has this group in the generated `pbxproj`, the UI however hides it when empty
- A longer term solution would be extend the project/target API to allow the cache mapper to add groups instead of `TuistGenerator` having awareness about the cache feature

Test Plan:

- Generate the fixture `ios_app_with_tests`
- Verify the `Frameworks` and `Cache` groups are no longer present
- Generate the fixture `ios_app_with_sdk`
- Verify the `Frameworks` group is still present (as there are system library dependencies)
- Verify the `Cache` group is no longer present
  • Loading branch information
kwridan committed Apr 2, 2024
1 parent f795995 commit b54a1cf
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ final class ProjectDescriptorGenerator: ProjectDescriptorGenerating {
graphTraverser: graphTraverser
)

groups.removeEmptyAuxiliaryGroups()

let xcodeProj = XcodeProj(workspace: workspace, pbxproj: pbxproj)
return ProjectDescriptor(
path: project.path,
Expand Down
18 changes: 18 additions & 0 deletions Sources/TuistGenerator/Generator/ProjectGroups.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ class ProjectGroups {
private let pbxproj: PBXProj
private let projectGroups: [String: PBXGroup]

private var auxiliaryGroups: [PBXGroup] {
// List of groups Xcode doesn't have by default if empty
//
// Note: The`Products` group is always included in the pbxproj but Xcode
// hides it in the UI if its empty.
[
frameworks,
cachedFrameworks,
]
}

// MARK: - Init

private init(
Expand Down Expand Up @@ -67,6 +78,13 @@ class ProjectGroups {
return group
}

func removeEmptyAuxiliaryGroups() {
for emptyGroup in auxiliaryGroups.filter(\.children.isEmpty) {
sortedMain.children.removeAll(where: { $0 == emptyGroup })
pbxproj.delete(object: emptyGroup)
}
}

static func generate(
project: Project,
pbxproj: PBXProj
Expand Down
51 changes: 51 additions & 0 deletions Tests/TuistGeneratorTests/Generator/ProjectGroupsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,49 @@ final class ProjectGroupsTests: XCTestCase {
])
}

func test_removeEmptyAuxiliaryGroups_removesEmptyGroups() throws {
// Given
let project = Project.test()
subject = ProjectGroups.generate(
project: project,
pbxproj: pbxproj
)

// When
subject.removeEmptyAuxiliaryGroups()

// Then
let paths = subject.sortedMain.children.map(\.nameOrPath)
XCTAssertEqual(paths, [
"Project",
"Products",
])
}

func test_removeEmptyAuxiliaryGroups_preservesNonEmptyGroups() throws {
// Given
let project = Project.test()
subject = ProjectGroups.generate(
project: project,
pbxproj: pbxproj
)

addFile(to: subject.frameworks)
addFile(to: subject.cachedFrameworks)

// When
subject.removeEmptyAuxiliaryGroups()

// Then
let paths = subject.sortedMain.children.map(\.nameOrPath)
XCTAssertEqual(paths, [
"Project",
"Frameworks",
"Cache",
"Products",
])
}

func test_targetFrameworks() throws {
subject = ProjectGroups.generate(
project: project,
Expand Down Expand Up @@ -213,4 +256,12 @@ final class ProjectGroupsTests: XCTestCase {
XCTAssertNil(main.tabWidth)
XCTAssertNil(main.wrapsLines)
}

// MARK: - Helpers

private func addFile(to group: PBXGroup) {
let file = PBXFileReference()
pbxproj.add(object: file)
group.children.append(file)
}
}

0 comments on commit b54a1cf

Please sign in to comment.