diff --git a/docs/bazel.md b/docs/bazel.md
index 7c62a1bcb6..41b488a3b5 100755
--- a/docs/bazel.md
+++ b/docs/bazel.md
@@ -62,12 +62,12 @@ load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcodeproj")
xcodeproj(name, adjust_schemes_for_swiftui_previews, associated_extra_files, bazel_path, bazel_env,
build_mode, config, default_xcode_configuration, extra_files,
fail_for_invalid_extra_files_targets, focused_targets, generation_mode,
- import_index_build_indexstores, install_directory, ios_device_cpus, ios_simulator_cpus,
- minimum_xcode_version, post_build, pre_build, project_name, project_options,
- scheme_autogeneration_mode, scheme_autogeneration_config, schemes, target_name_mode,
- top_level_targets, tvos_device_cpus, tvos_simulator_cpus, unfocused_targets,
- visionos_device_cpus, visionos_simulator_cpus, watchos_device_cpus, watchos_simulator_cpus,
- xcode_configurations, xcschemes, kwargs)
+ import_index_build_indexstores, include_package_generated_files_group, install_directory,
+ ios_device_cpus, ios_simulator_cpus, minimum_xcode_version, post_build, pre_build,
+ project_name, project_options, scheme_autogeneration_mode, scheme_autogeneration_config,
+ schemes, target_name_mode, top_level_targets, tvos_device_cpus, tvos_simulator_cpus,
+ unfocused_targets, visionos_device_cpus, visionos_simulator_cpus, watchos_device_cpus,
+ watchos_simulator_cpus, xcode_configurations, xcschemes, kwargs)
Creates an `.xcodeproj` file in the workspace when run.
@@ -111,6 +111,7 @@ xcodeproj(
| focused_targets | Optional. A `list` of target labels as `string` values.
If specified, only these targets will be included in the generated project; all other targets will be excluded, as if they were listed explicitly in the `unfocused_targets` argument. The labels must match transitive dependencies of the targets specified in the `top_level_targets` argument. | `[]` |
| generation_mode | Optional. Determines how the project is generated.
- `incremental`: The project is generated in pieces by multiple Bazel actions and then combined together. This allows for incremental generation where some of those pieces can be reused in subsequent project generations.
The way information is collected and processed has also changed compared to legacy generation mode. This has resulted in some bug fixes and improvements that don't exist in legacy generation mode.
**Note:** Only `build_mode = "bazel"` is supported in this mode.
**Note:** The [`xcschemes`](#xcodeproj-xcschemes) attribute is used instead of [`schemes`](#xcodeproj-schemes) in this mode. - `legacy`: The project is generated by a monolith Bazel action.
This mode is deprecated and will be removed in a future version of **rules_xcodeproj**.
| `"incremental"` |
| import_index_build_indexstores | Optional. Whether to import the index stores generated by Index Build.
This is useful if you want to use the index stores generated by Index Build to speed up Xcode's indexing process. You may not want this enabled if the additional work (mainly disk IO) of importing the index stores is not worth it for your project.
This only applies when using `generation_mode = "incremental"`. | `True` |
+| include_package_generated_files_group | Optional. Whether the project will create a `Bazel Generated Files` child group for packages with generated files.
This is useful for finding generated files more easily in the project navigator by creating a child group in the path tree for each generated files' package.
This only applies when using `generation_mode = "incremental"`. | `False` |
| install_directory | Optional. The directory where the generated project will be written to.
The path is relative to the workspace root.
Defaults to the directory that the `xcodeproj` target is declared in (e.g. if the `xcodeproj` target is declared in `//foo/bar:BUILD` then the default value is `"foo/bar"`). Use `""` to have the project generated in the workspace root. | `None` |
| ios_device_cpus | Optional. The value to use for `--ios_multi_cpus` when building the transitive dependencies of the targets specified in the `top_level_targets` argument with the `"device"` `target_environment`.
**Warning:** Changing this value will affect the Starlark transition hash of all transitive dependencies of the targets specified in the `top_level_targets` argument with the `"device"` `target_environment`, even if they aren't iOS targets. | `"arm64"` |
| ios_simulator_cpus | Optional. The value to use for `--ios_multi_cpus` when building the transitive dependencies of the targets specified in the `top_level_targets` argument with the `"simulator"` `target_environment`.
If no value is specified, it defaults to the simulator cpu that goes with `--host_cpu` (i.e. `sim_arm64` on Apple Silicon and `x86_64` on Intel).
**Warning:** Changing this value will affect the Starlark transition hash of all transitive dependencies of the targets specified in the `top_level_targets` argument with the `"simulator"` `target_environment`, even if they aren't iOS targets. | `None` |
diff --git a/examples/integration/BUILD b/examples/integration/BUILD
index 8307c6e38a..1c1dc1b0a1 100644
--- a/examples/integration/BUILD
+++ b/examples/integration/BUILD
@@ -65,6 +65,7 @@ string_flag(
extra_files = EXTRA_FILES,
fail_for_invalid_extra_files_targets = FAIL_FOR_INVALID_EXTRA_FILES_TARGETS,
generation_mode = generation_mode,
+ include_package_generated_files_group = True,
ios_simulator_cpus = simulator_cpu,
pre_build = PRE_BUILD,
project_name = "Integration",
diff --git a/test/internal/pbxproj_partials/write_files_and_groups_tests.bzl b/test/internal/pbxproj_partials/write_files_and_groups_tests.bzl
index 688442fc4b..566db3a530 100644
--- a/test/internal/pbxproj_partials/write_files_and_groups_tests.bzl
+++ b/test/internal/pbxproj_partials/write_files_and_groups_tests.bzl
@@ -50,6 +50,8 @@ def _write_files_and_groups_test_impl(ctx):
# Act
+ mock_files = [mock_actions.mock_file(f) for f in ctx.attr.files]
+
(
pbxproject_known_regions,
files_and_groups,
@@ -63,9 +65,10 @@ def _write_files_and_groups_test_impl(ctx):
compile_stub_needed = ctx.attr.compile_stub_needed,
execution_root_file = ctx.attr.execution_root_file,
generator_name = "a_generator_name",
- files = depset(ctx.attr.files),
+ files = depset(mock_files),
file_paths = depset(ctx.attr.file_paths),
folders = depset(ctx.attr.folders),
+ include_package_generated_files_group = False,
install_path = ctx.attr.install_path,
project_options = ctx.attr.project_options,
selected_model_versions_file = ctx.attr.selected_model_versions_file,
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateGroup.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateGroup.swift
index af96e0414a..6550f16713 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateGroup.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateGroup.swift
@@ -27,7 +27,8 @@ extension ElementCreator {
for node: PathTreeNode,
parentBazelPath: BazelPath,
specialRootGroupType: SpecialRootGroupType?,
- createGroupChild: CreateGroupChild
+ createGroupChild: CreateGroupChild,
+ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild.ElementAndChildren {
return callable(
/*node:*/ node,
@@ -35,7 +36,8 @@ extension ElementCreator {
/*specialRootGroupType:*/ specialRootGroupType,
/*createGroupChild:*/ createGroupChild,
/*createGroupChildElements:*/ createGroupChildElements,
- /*createGroupElement:*/ createGroupElement
+ /*createGroupElement:*/ createGroupElement,
+ /*createSpecialGroupElement:*/ createSpecialGroupElement
)
}
}
@@ -50,7 +52,8 @@ extension ElementCreator.CreateGroup {
_ specialRootGroupType: SpecialRootGroupType?,
_ createGroupChild: ElementCreator.CreateGroupChild,
_ createGroupChildElements: ElementCreator.CreateGroupChildElements,
- _ createGroupElement: ElementCreator.CreateGroupElement
+ _ createGroupElement: ElementCreator.CreateGroupElement,
+ _ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild.ElementAndChildren
static func defaultCallable(
@@ -59,16 +62,24 @@ extension ElementCreator.CreateGroup {
specialRootGroupType: SpecialRootGroupType?,
createGroupChild: ElementCreator.CreateGroupChild,
createGroupChildElements: ElementCreator.CreateGroupChildElements,
- createGroupElement: ElementCreator.CreateGroupElement
+ createGroupElement: ElementCreator.CreateGroupElement,
+ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild.ElementAndChildren {
- let bazelPath = parentBazelPath + node
+ let isBazelGenerated = node.name.hasPrefix("bazel-out")
+ let bazelPath: BazelPath
+ if isBazelGenerated {
+ bazelPath = BazelPath(node.name)
+ } else {
+ bazelPath = parentBazelPath + node
+ }
let name = node.name
let groupChildren = node.children.map { node in
return createGroupChild(
for: node,
parentBazelPath: bazelPath,
- specialRootGroupType: specialRootGroupType
+ specialRootGroupType: specialRootGroupType,
+ createSpecialGroupElement: createSpecialGroupElement
)
}
@@ -76,16 +87,29 @@ extension ElementCreator.CreateGroup {
parentBazelPath: bazelPath,
groupChildren: groupChildren
)
-
- let (
- group,
- resolvedRepository
- ) = createGroupElement(
- name: name,
- bazelPath: bazelPath,
- specialRootGroupType: specialRootGroupType,
- childIdentifiers: children.elements.map(\.object.identifier)
- )
+
+ let group: Element
+ var resolvedRepository: ResolvedRepository? = nil
+ if isBazelGenerated {
+ group = createSpecialGroupElement(
+ specialRootGroupType: .bazelGenerated,
+ childIdentifiers: children.elements.map(\.object.identifier),
+ useRootStableIdentifiers: false,
+ bazelPath: bazelPath
+ )
+ } else {
+ (
+ group,
+ resolvedRepository
+ ) = createGroupElement(
+ name: name,
+ bazelPath: bazelPath,
+ specialRootGroupType: specialRootGroupType,
+ childIdentifiers: children.elements.map(\.object.identifier)
+ )
+ }
+
+
return GroupChild.ElementAndChildren(
bazelPath: bazelPath,
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateGroupChild.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateGroupChild.swift
index b728376241..afb3fcd7a3 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateGroupChild.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateGroupChild.swift
@@ -29,7 +29,8 @@ extension ElementCreator {
func callAsFunction(
for node: PathTreeNode,
parentBazelPath: BazelPath,
- specialRootGroupType: SpecialRootGroupType?
+ specialRootGroupType: SpecialRootGroupType?,
+ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild {
return callable(
/*node:*/ node,
@@ -39,7 +40,8 @@ extension ElementCreator {
/*createGroup:*/ createGroup,
/*createGroupChild:*/ self,
/*createLocalizedFiles:*/ createLocalizedFiles,
- /*createVersionGroup:*/ createVersionGroup
+ /*createVersionGroup:*/ createVersionGroup,
+ /*createSpecialGroupElement:*/ createSpecialGroupElement
)
}
}
@@ -56,7 +58,8 @@ extension ElementCreator.CreateGroupChild {
_ createGroup: ElementCreator.CreateGroup,
_ createGroupChild: ElementCreator.CreateGroupChild,
_ createLocalizedFiles: ElementCreator.CreateLocalizedFiles,
- _ createVersionGroup: ElementCreator.CreateVersionGroup
+ _ createVersionGroup: ElementCreator.CreateVersionGroup,
+ _ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild
static func defaultCallable(
@@ -67,7 +70,8 @@ extension ElementCreator.CreateGroupChild {
createGroup: ElementCreator.CreateGroup,
createGroupChild: ElementCreator.CreateGroupChild,
createLocalizedFiles: ElementCreator.CreateLocalizedFiles,
- createVersionGroup: ElementCreator.CreateVersionGroup
+ createVersionGroup: ElementCreator.CreateVersionGroup,
+ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChild {
guard !node.children.isEmpty else {
// File
@@ -108,7 +112,8 @@ extension ElementCreator.CreateGroupChild {
for: node,
parentBazelPath: parentBazelPath,
specialRootGroupType: specialRootGroupType,
- createGroupChild: createGroupChild
+ createGroupChild: createGroupChild,
+ createSpecialGroupElement: createSpecialGroupElement
)
)
}
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateGroupElement.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateGroupElement.swift
index dd7675e8fd..ce595d1acc 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateGroupElement.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateGroupElement.swift
@@ -85,7 +85,6 @@ extension ElementCreator.CreateGroupElement {
} else {
nameAttribute = ""
}
-
// The tabs for indenting are intentional
let content = #"""
{
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateRootElements.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateRootElements.swift
index 5e3203a913..04d895a7ad 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateRootElements.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateRootElements.swift
@@ -9,6 +9,7 @@ extension ElementCreator {
private let createGroupChildElements: CreateGroupChildElements
private let createInternalGroup: CreateInternalGroup
private let createSpecialRootGroup: CreateSpecialRootGroup
+ private let createSpecialGroupElement: CreateSpecialRootGroupElement
private let callable: Callable
@@ -23,6 +24,7 @@ extension ElementCreator {
createGroupChildElements: CreateGroupChildElements,
createInternalGroup: CreateInternalGroup,
createSpecialRootGroup: CreateSpecialRootGroup,
+ createSpecialGroupElement: CreateSpecialRootGroupElement,
callable: @escaping Callable
) {
self.includeCompileStub = includeCompileStub
@@ -32,6 +34,7 @@ extension ElementCreator {
self.createGroupChildElements = createGroupChildElements
self.createInternalGroup = createInternalGroup
self.createSpecialRootGroup = createSpecialRootGroup
+ self.createSpecialGroupElement = createSpecialGroupElement
self.callable = callable
}
@@ -47,7 +50,8 @@ extension ElementCreator {
/*createGroupChild:*/ createGroupChild,
/*createGroupChildElements:*/ createGroupChildElements,
/*createInternalGroup:*/ createInternalGroup,
- /*createSpecialRootGroup:*/ createSpecialRootGroup
+ /*createSpecialRootGroup:*/ createSpecialRootGroup,
+ /*createSpecialGroupElement:*/ createSpecialGroupElement
)
}
}
@@ -64,7 +68,8 @@ extension ElementCreator.CreateRootElements {
_ createGroupChild: ElementCreator.CreateGroupChild,
_ createGroupChildElements: ElementCreator.CreateGroupChildElements,
_ createInternalGroup: ElementCreator.CreateInternalGroup,
- _ createSpecialRootGroup: ElementCreator.CreateSpecialRootGroup
+ _ createSpecialRootGroup: ElementCreator.CreateSpecialRootGroup,
+ _ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChildElements
static func defaultCallable(
@@ -75,7 +80,8 @@ extension ElementCreator.CreateRootElements {
createGroupChild: ElementCreator.CreateGroupChild,
createGroupChildElements: ElementCreator.CreateGroupChildElements,
createInternalGroup: ElementCreator.CreateInternalGroup,
- createSpecialRootGroup: ElementCreator.CreateSpecialRootGroup
+ createSpecialRootGroup: ElementCreator.CreateSpecialRootGroup,
+ createSpecialGroupElement: ElementCreator.CreateSpecialRootGroupElement
) -> GroupChildElements {
let bazelPath = BazelPath("")
@@ -117,7 +123,8 @@ extension ElementCreator.CreateRootElements {
createGroupChild(
for: node,
parentBazelPath: bazelPath,
- specialRootGroupType: nil
+ specialRootGroupType: nil,
+ createSpecialGroupElement: createSpecialGroupElement
)
)
}
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroup.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroup.swift
index a3ab889933..9534eaf9bd 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroup.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroup.swift
@@ -65,7 +65,8 @@ extension ElementCreator.CreateSpecialRootGroup {
return createGroupChild(
for: node,
parentBazelPath: bazelPath,
- specialRootGroupType: specialRootGroupType
+ specialRootGroupType: specialRootGroupType,
+ createSpecialGroupElement: createSpecialRootGroupElement
)
}
@@ -76,7 +77,9 @@ extension ElementCreator.CreateSpecialRootGroup {
let group = createSpecialRootGroupElement(
specialRootGroupType: specialRootGroupType,
- childIdentifiers: children.elements.map(\.object.identifier)
+ childIdentifiers: children.elements.map(\.object.identifier),
+ useRootStableIdentifiers: true,
+ bazelPath: bazelPath
)
return GroupChild.ElementAndChildren(
diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroupElement.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroupElement.swift
index 91e1453780..0fed4b0f0a 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroupElement.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/CreateSpecialRootGroupElement.swift
@@ -2,12 +2,15 @@ import PBXProj
extension ElementCreator {
struct CreateSpecialRootGroupElement {
+ private let createIdentifier: ElementCreator.CreateIdentifier
+
private let callable: Callable
/// - Parameters:
/// - callable: The function that will be called in
/// `callAsFunction()`.
- init(callable: @escaping Callable = Self.defaultCallable) {
+ init(createIdentifier: CreateIdentifier, callable: @escaping Callable = Self.defaultCallable) {
+ self.createIdentifier = createIdentifier
self.callable = callable
}
@@ -15,11 +18,16 @@ extension ElementCreator {
/// External Repositories").
func callAsFunction(
specialRootGroupType: SpecialRootGroupType,
- childIdentifiers: [String]
+ childIdentifiers: [String],
+ useRootStableIdentifiers: Bool,
+ bazelPath: BazelPath
) -> Element {
return callable(
/*specialRootGroupType:*/ specialRootGroupType,
- /*childIdentifiers:*/ childIdentifiers
+ /*childIdentifiers:*/ childIdentifiers,
+ /*useRootStableIdentifiers:*/ useRootStableIdentifiers,
+ /*createIdentifier:*/ createIdentifier,
+ /*bazelPath:*/ bazelPath
)
}
}
@@ -30,27 +38,35 @@ extension ElementCreator {
extension ElementCreator.CreateSpecialRootGroupElement {
typealias Callable = (
_ specialRootGroupType: SpecialRootGroupType,
- _ childIdentifiers: [String]
+ _ childIdentifiers: [String],
+ _ useRootStableIdentifiers: Bool,
+ _ createIdentifier: ElementCreator.CreateIdentifier,
+ _ bazelPath: BazelPath
) -> Element
static func defaultCallable(
specialRootGroupType: SpecialRootGroupType,
- childIdentifiers: [String]
+ childIdentifiers: [String],
+ useRootStableIdentifiers: Bool,
+ createIdentifier: ElementCreator.CreateIdentifier,
+ bazelPath: BazelPath
) -> Element {
- let identifier: String
+ let identifier: String = groupIdentifier(
+ useStable: useRootStableIdentifiers,
+ bazelPath: bazelPath,
+ type: specialRootGroupType,
+ createIdentifier: createIdentifier
+ )
let name: String
let path: String
let sortOrder: Element.SortOrder
switch specialRootGroupType {
case .legacyBazelExternal, .siblingBazelExternal:
- identifier =
- Identifiers.FilesAndGroups.bazelExternalRepositoriesGroup
name = "Bazel External Repositories"
path = "../../external"
sortOrder = .bazelExternalRepositories
case .bazelGenerated:
- identifier = Identifiers.FilesAndGroups.bazelGeneratedFilesGroup
name = "Bazel Generated Files"
path = "bazel-out"
sortOrder = .bazelGenerated
@@ -78,6 +94,26 @@ extension ElementCreator.CreateSpecialRootGroupElement {
sortOrder: sortOrder
)
}
+
+ private static func groupIdentifier(
+ useStable: Bool,
+ bazelPath: BazelPath,
+ type: SpecialRootGroupType,
+ createIdentifier: ElementCreator.CreateIdentifier
+ ) -> String {
+ if useStable {
+ switch type {
+ case .legacyBazelExternal, .siblingBazelExternal:
+ return
+ Identifiers.FilesAndGroups.bazelExternalRepositoriesGroup
+
+ case .bazelGenerated:
+ return Identifiers.FilesAndGroups.bazelGeneratedFilesGroup
+ }
+ } else {
+ return createIdentifier(path: bazelPath.path, name: bazelPath.path, type: .group)
+ }
+ }
}
enum SpecialRootGroupType {
diff --git a/tools/generators/files_and_groups/src/ElementCreator/ElementCreatorEnvironment.swift b/tools/generators/files_and_groups/src/ElementCreator/ElementCreatorEnvironment.swift
index 4b2f6a896c..0d758730dc 100644
--- a/tools/generators/files_and_groups/src/ElementCreator/ElementCreatorEnvironment.swift
+++ b/tools/generators/files_and_groups/src/ElementCreator/ElementCreatorEnvironment.swift
@@ -54,7 +54,7 @@ extension ElementCreator {
/// `CreateSpecialRootGroup.init()`.
let createSpecialRootGroupCallable: CreateSpecialRootGroup.Callable
- let createSpecialRootGroupElement: CreateSpecialRootGroupElement
+ let createSpecialRootGroupElementCallable: CreateSpecialRootGroupElement.Callable
/// Passed to the `callable` parameter of `CreateVariantGroup.init()`.
let createVariantGroupCallable: CreateVariantGroup.Callable
@@ -173,11 +173,13 @@ extension ElementCreator.Environment {
let createInternalGroup = ElementCreator.CreateInternalGroup(
callable: createInternalGroupCallable
)
+
+ let createSpecialGroupElement = ElementCreator.CreateSpecialRootGroupElement(createIdentifier: createIdentifier)
let createSpecialRootGroup = ElementCreator.CreateSpecialRootGroup(
createGroupChild: createGroupChild,
createGroupChildElements: createGroupChildElements,
- createSpecialRootGroupElement: createSpecialRootGroupElement,
+ createSpecialRootGroupElement: createSpecialGroupElement,
callable: createSpecialRootGroupCallable
)
@@ -189,6 +191,7 @@ extension ElementCreator.Environment {
createGroupChildElements: createGroupChildElements,
createInternalGroup: createInternalGroup,
createSpecialRootGroup: createSpecialRootGroup,
+ createSpecialGroupElement: createSpecialGroupElement,
callable: createRootElementsCallable
)
}
@@ -222,8 +225,8 @@ extension ElementCreator.Environment {
ElementCreator.CreateRootElements.defaultCallable,
createSpecialRootGroupCallable:
ElementCreator.CreateSpecialRootGroup.defaultCallable,
- createSpecialRootGroupElement:
- ElementCreator.CreateSpecialRootGroupElement(),
+ createSpecialRootGroupElementCallable:
+ ElementCreator.CreateSpecialRootGroupElement.defaultCallable,
createVariantGroupCallable:
ElementCreator.CreateVariantGroup.defaultCallable,
createVariantGroupElementCallable:
diff --git a/tools/generators/files_and_groups/src/Generator/CalculatePathTree.swift b/tools/generators/files_and_groups/src/Generator/CalculatePathTree.swift
index 7bba5e7fe1..e277328fc9 100644
--- a/tools/generators/files_and_groups/src/Generator/CalculatePathTree.swift
+++ b/tools/generators/files_and_groups/src/Generator/CalculatePathTree.swift
@@ -8,13 +8,24 @@ extension Generator {
var nodesByComponentCount: [Int: [PathTreeNodeToVisit]] = [:]
for path in paths {
- let components = path.path.split(separator: "/")
- nodesByComponentCount[components.count, default: []]
- .append(PathTreeNodeToVisit(
- components: components,
- isFolder: path.isFolder,
- children: []
- ))
+ if path.path.hasPrefix("bazel-out"), let owner = path.owner {
+ let generatedPath = "\(owner)/\(path.path)"
+ let generatedComponents = generatedPath.split(separator: "/")
+ nodesByComponentCount[generatedComponents.count, default: []]
+ .append(PathTreeNodeToVisit(
+ components: generatedComponents,
+ isFolder: path.isFolder,
+ children: []
+ ))
+ } else {
+ let components = path.path.split(separator: "/")
+ nodesByComponentCount[components.count, default: []]
+ .append(PathTreeNodeToVisit(
+ components: components,
+ isFolder: path.isFolder,
+ children: []
+ ))
+ }
}
for componentCount in (1...nodesByComponentCount.keys.max()!)
diff --git a/tools/generators/files_and_groups/src/Generator/ReadFilePathsFile.swift b/tools/generators/files_and_groups/src/Generator/ReadFilePathsFile.swift
index 47a44f826b..fa6ab7f542 100644
--- a/tools/generators/files_and_groups/src/Generator/ReadFilePathsFile.swift
+++ b/tools/generators/files_and_groups/src/Generator/ReadFilePathsFile.swift
@@ -32,6 +32,13 @@ extension Generator.ReadFilePathsFile {
_ url: URL
) async throws -> [BazelPath] {
return try await url.lines.collect()
- .map { BazelPath($0, isFolder: false) }
+ .map { line in
+ let components = line.split(separator: "--").map(String.init)
+ if components.count == 2 {
+ return BazelPath(components[0], isFolder: false, owner: components[1])
+ } else {
+ return BazelPath(components[0], isFolder: false)
+ }
+ }
}
}
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateGroup+Testing.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateGroup+Testing.swift
index c62a029b6c..d29a16b83e 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateGroup+Testing.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateGroup+Testing.swift
@@ -19,7 +19,6 @@ extension ElementCreator.CreateGroup {
groupChildElement: GroupChild.ElementAndChildren
) -> (mock: Self, tracker: MockTracker) {
let mockTracker = MockTracker()
-
let mocked = Self(
createGroupChildElements:
ElementCreator.Stubs.createGroupChildElements,
@@ -30,7 +29,8 @@ extension ElementCreator.CreateGroup {
specialRootGroupType,
createGroupChild,
createGroupChildElements,
- createGroupElement
+ createGroupElement,
+ createSpecialGroupElement
in
mockTracker.called.append(.init(
node: node,
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateGroupChild+Testing.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateGroupChild+Testing.swift
index 9010e29529..130395c2b0 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateGroupChild+Testing.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateGroupChild+Testing.swift
@@ -46,7 +46,8 @@ extension ElementCreator.CreateGroupChild {
createFile,
createGroupElement,
createLocalizedFiles,
- createVersionGroup
+ createVersionGroup,
+ createSpecialGroupElement
in
mockTracker.called.append(.init(
node: node,
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateGroupTests.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateGroupTests.swift
index a624fa3244..d127d5807b 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateGroupTests.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateGroupTests.swift
@@ -179,7 +179,9 @@ final class CreateGroupTests: XCTestCase {
specialRootGroupType: specialRootGroupType,
createGroupChild: createGroupChild.mock,
createGroupChildElements: createGroupChildElements.mock,
- createGroupElement: createGroupElement.mock
+ createGroupElement: createGroupElement.mock,
+ createSpecialGroupElement: ElementCreator.Stubs.createSpecialRootGroupElement
+
)
// Assert
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateRootElementsTests.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateRootElementsTests.swift
index 05a6bdc37a..5155057969 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateRootElementsTests.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateRootElementsTests.swift
@@ -304,6 +304,8 @@ final class CreateRootElementsTests: XCTestCase {
let createGroupChildElements = ElementCreator.CreateGroupChildElements
.mock(groupChildElements: stubbedRootElements)
+ let createSpecialGroupElement = ElementCreator.CreateSpecialRootGroupElement(createIdentifier: ElementCreator.CreateIdentifier())
+
// Act
let rootElements = ElementCreator.CreateRootElements.defaultCallable(
@@ -314,7 +316,8 @@ final class CreateRootElementsTests: XCTestCase {
createGroupChild: createGroupChild.mock,
createGroupChildElements: createGroupChildElements.mock,
createInternalGroup: createInternalGroup.mock,
- createSpecialRootGroup: createSpecialRootGroup.mock
+ createSpecialRootGroup: createSpecialRootGroup.mock,
+ createSpecialGroupElement: createSpecialGroupElement
)
// Assert
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElement+Testing.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElement+Testing.swift
index 2c45b8c602..e32e0bf4a3 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElement+Testing.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElement+Testing.swift
@@ -14,11 +14,12 @@ extension ElementCreator.CreateSpecialRootGroupElement {
fileprivate(set) var called: [Called] = []
}
- static func mock(element: Element) -> (mock: Self, tracker: MockTracker) {
+ static func mock(element: Element, createIdentifier: ElementCreator.CreateIdentifier) -> (mock: Self, tracker: MockTracker) {
let mockTracker = MockTracker()
let mocked = Self(
- callable: { specialRootGroupType, childIdentifiers in
+ createIdentifier: createIdentifier,
+ callable: { specialRootGroupType, childIdentifiers, useRootStableIdentifiers, createIdentifier, bazelPath in
mockTracker.called.append(.init(
specialRootGroupType: specialRootGroupType,
childIdentifiers: childIdentifiers
@@ -35,7 +36,7 @@ extension ElementCreator.CreateSpecialRootGroupElement {
extension ElementCreator.CreateSpecialRootGroupElement {
static func stub(element: Element) -> Self {
- let (stub, _) = mock(element: element)
+ let (stub, _) = mock(element: element, createIdentifier: ElementCreator.Stubs.createIdentifier)
return stub
}
}
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElementTests.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElementTests.swift
index 43b8d9f4e1..064c99dde9 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElementTests.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupElementTests.swift
@@ -38,7 +38,10 @@ final class CreateSpecialRootGroupElementTests: XCTestCase {
let element = ElementCreator.CreateSpecialRootGroupElement.defaultCallable(
specialRootGroupType: specialRootGroupType,
- childIdentifiers: childIdentifiers
+ childIdentifiers: childIdentifiers,
+ useRootStableIdentifiers: true,
+ createIdentifier: ElementCreator.Stubs.createIdentifier,
+ bazelPath: BazelPath(stringLiteral: "foo/bar")
)
// Assert
@@ -80,7 +83,10 @@ final class CreateSpecialRootGroupElementTests: XCTestCase {
let element = ElementCreator.CreateSpecialRootGroupElement.defaultCallable(
specialRootGroupType: specialRootGroupType,
- childIdentifiers: childIdentifiers
+ childIdentifiers: childIdentifiers,
+ useRootStableIdentifiers: true,
+ createIdentifier: ElementCreator.Stubs.createIdentifier,
+ bazelPath: BazelPath(stringLiteral: "foo/bar")
)
// Assert
@@ -122,7 +128,10 @@ final class CreateSpecialRootGroupElementTests: XCTestCase {
let element = ElementCreator.CreateSpecialRootGroupElement.defaultCallable(
specialRootGroupType: specialRootGroupType,
- childIdentifiers: childIdentifiers
+ childIdentifiers: childIdentifiers,
+ useRootStableIdentifiers: true,
+ createIdentifier: ElementCreator.Stubs.createIdentifier,
+ bazelPath: BazelPath(stringLiteral: "foo/bar")
)
// Assert
diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupTests.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupTests.swift
index 7845f74151..22415b8bb3 100644
--- a/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupTests.swift
+++ b/tools/generators/files_and_groups/test/ElementCreator/CreateSpecialRootGroupTests.swift
@@ -188,7 +188,7 @@ final class CreateSpecialRootGroupTests: XCTestCase {
]
let createSpecialRootGroupElement =
ElementCreator.CreateSpecialRootGroupElement
- .mock(element: stubbedElement)
+ .mock(element: stubbedElement, createIdentifier: ElementCreator.Stubs.createIdentifier)
let expectedResult = GroupChild.ElementAndChildren(
bazelPath: expectedBazelPath,
diff --git a/tools/generators/lib/PBXProj/src/BazelPath.swift b/tools/generators/lib/PBXProj/src/BazelPath.swift
index e28a5cf0ef..b4dc4a3a76 100644
--- a/tools/generators/lib/PBXProj/src/BazelPath.swift
+++ b/tools/generators/lib/PBXProj/src/BazelPath.swift
@@ -4,10 +4,12 @@ import Foundation
public struct BazelPath: Hashable {
public var path: String
public var isFolder: Bool
+ public var owner: String?
- public init(_ path: String, isFolder: Bool = false) {
+ public init(_ path: String, isFolder: Bool = false, owner: String? = nil) {
self.path = path
self.isFolder = isFolder
+ self.owner = owner
}
}
diff --git a/xcodeproj/internal/pbxproj_partials.bzl b/xcodeproj/internal/pbxproj_partials.bzl
index 56516574b2..48e0c96d1c 100644
--- a/xcodeproj/internal/pbxproj_partials.bzl
+++ b/xcodeproj/internal/pbxproj_partials.bzl
@@ -67,6 +67,12 @@ def _generated_file_path(file):
return _always_generated_file_path(file)
+def _map_file_with_owner(file):
+ if hasattr(file, "owner") and file.owner != None:
+ return "{}--{}".format(file.path, file.owner.package)
+ else:
+ return file.path
+
# Partials
# enum of flags, mainly to ensure the strings are frozen and reused
@@ -359,6 +365,7 @@ def _write_files_and_groups(
file_paths,
folders,
generator_name,
+ include_package_generated_files_group,
install_path,
project_options,
selected_model_versions_file,
@@ -381,6 +388,7 @@ def _write_files_and_groups(
file paths.
folders: A `depset` of paths to folders to include in the project.
generator_name: The name of the `xcodeproj` generator target.
+ include_package_generated_files_group: Whether to generate child `Bazel Generated Files` groups.
install_path: The workspace relative path to where the final
`.xcodeproj` will be written.
project_options: A `dict` as returned by `project_options`.
@@ -432,7 +440,10 @@ def _write_files_and_groups(
file_path_args = actions.args()
file_path_args.set_param_file_format("multiline")
- file_path_args.add_all(files)
+ if include_package_generated_files_group:
+ file_path_args.add_all(files, map_each = _map_file_with_owner)
+ else:
+ file_path_args.add_all(files)
# TODO: Consider moving normalization into `args.add_all.map_each`
file_path_args.add_all(file_paths)
diff --git a/xcodeproj/internal/templates/generator.incremental.BUILD.bazel b/xcodeproj/internal/templates/generator.incremental.BUILD.bazel
index 36a29e8433..f68e52f4b9 100644
--- a/xcodeproj/internal/templates/generator.incremental.BUILD.bazel
+++ b/xcodeproj/internal/templates/generator.incremental.BUILD.bazel
@@ -19,6 +19,7 @@ xcodeproj(
default_xcode_configuration = %default_xcode_configuration%,
generation_shard_count = %generation_shard_count%,
import_index_build_indexstores = %import_index_build_indexstores%,
+ include_package_generated_files_group = %include_package_generated_files_group%,
install_path = "%install_path%",
ios_device_cpus = "%ios_device_cpus%",
ios_simulator_cpus = "%ios_simulator_cpus%",
diff --git a/xcodeproj/internal/xcodeproj_incremental_rule.bzl b/xcodeproj/internal/xcodeproj_incremental_rule.bzl
index 12e1bc2f52..1140cb22a1 100644
--- a/xcodeproj/internal/xcodeproj_incremental_rule.bzl
+++ b/xcodeproj/internal/xcodeproj_incremental_rule.bzl
@@ -321,6 +321,7 @@ def _write_project_contents(
default_xcode_configuration,
files_and_groups_generator,
generation_shard_count,
+ include_package_generated_files_group,
import_index_build_indexstores,
index_import,
install_path,
@@ -430,6 +431,7 @@ def _write_project_contents(
file_paths = file_paths,
folders = folders,
generator_name = name,
+ include_package_generated_files_group = include_package_generated_files_group,
install_path = install_path,
project_options = project_options,
selected_model_versions_file = selected_model_versions_file,
@@ -648,6 +650,7 @@ Are you using an `alias`? `xcodeproj.focused_targets` and \
default_xcode_configuration = default_xcode_configuration,
files_and_groups_generator = ctx.executable._files_and_groups_generator,
generation_shard_count = ctx.attr.generation_shard_count,
+ include_package_generated_files_group = ctx.attr.include_package_generated_files_group,
import_index_build_indexstores = (
ctx.attr.import_index_build_indexstores
),
@@ -796,6 +799,7 @@ def _xcodeproj_incremental_attrs(
"default_xcode_configuration": attr.string(),
"generation_shard_count": attr.int(mandatory = True),
"import_index_build_indexstores": attr.bool(mandatory = True),
+ "include_package_generated_files_group": attr.bool(mandatory = True),
"install_path": attr.string(mandatory = True),
"minimum_xcode_version": attr.string(mandatory = True),
"owned_extra_files": attr.label_keyed_string_dict(allow_files = True),
diff --git a/xcodeproj/internal/xcodeproj_macro.bzl b/xcodeproj/internal/xcodeproj_macro.bzl
index 0a4b16038e..3f1c5c55fa 100644
--- a/xcodeproj/internal/xcodeproj_macro.bzl
+++ b/xcodeproj/internal/xcodeproj_macro.bzl
@@ -31,6 +31,7 @@ def xcodeproj(
focused_targets = [],
generation_mode = "incremental",
import_index_build_indexstores = True,
+ include_package_generated_files_group = False,
install_directory = None,
ios_device_cpus = "arm64",
ios_simulator_cpus = None,
@@ -215,6 +216,14 @@ def xcodeproj(
this enabled if the additional work (mainly disk IO) of importing
the index stores is not worth it for your project.
+ This only applies when using `generation_mode = "incremental"`.
+ include_package_generated_files_group: Optional. Whether the project
+ will create a `Bazel Generated Files` child group for packages with generated
+ files.
+
+ This is useful for finding generated files more easily in the project navigator
+ by creating a child group in the path tree for each generated files' package.
+
This only applies when using `generation_mode = "incremental"`.
install_directory: Optional. The directory where the generated project
will be written to.
@@ -638,6 +647,7 @@ for {configuration} ({new_keys}) do not match keys of other configurations \
generation_mode = generation_mode,
generation_shard_count = generation_shard_count,
import_index_build_indexstores = import_index_build_indexstores,
+ include_package_generated_files_group = include_package_generated_files_group,
install_directory = install_directory,
ios_device_cpus = ios_device_cpus,
ios_simulator_cpus = ios_simulator_cpus,
diff --git a/xcodeproj/internal/xcodeproj_runner.bzl b/xcodeproj/internal/xcodeproj_runner.bzl
index e1169cc9e9..f67a0a742d 100644
--- a/xcodeproj/internal/xcodeproj_runner.bzl
+++ b/xcodeproj/internal/xcodeproj_runner.bzl
@@ -257,6 +257,9 @@ def _write_generator_build_file(
"%import_index_build_indexstores%": str(
attr.import_index_build_indexstores,
),
+ "%include_package_generated_files_group%": str(
+ attr.include_package_generated_files_group,
+ ),
"%install_directory%": attr.install_directory,
"%install_path%": install_path,
"%ios_device_cpus%": attr.ios_device_cpus,
@@ -552,6 +555,7 @@ xcodeproj_runner = rule(
),
"generation_shard_count": attr.int(mandatory = True),
"import_index_build_indexstores": attr.bool(mandatory = True),
+ "include_package_generated_files_group": attr.bool(mandatory = True),
"install_directory": attr.string(mandatory = True),
"ios_device_cpus": attr.string(mandatory = True),
"ios_simulator_cpus": attr.string(),