func run()

in Sources/XCRemoteCache/Commands/Prepare/Integrate/XcodeProjIntegrate.swift [135:222]


    func run() throws {
        let outputFile = output ?? projectURL
        let projectRoot = projectURL.deletingLastPathComponent()

        let projectPath = Path(projectURL.path)
        let outputPath = Path(outputFile.path)

        // Override all extra configs (default to 'user.rc', next to the main '.rcinfo' file)
        let initialOverride = IntegrationCacheConfig(
            recommendedCacheAddress: nil,
            xcccFile: binaries.cc.path,
            mode: mode
        )
        try storeRCOverride(initialOverride, configOverrideLocation: configOverride)

        if case .consumer = mode {
            // require successful preparation
            do {

                // Call xcprepare to probe if XCRemoteCache can be safely used
                let args = ["--configuration"] + consumerEligibleConfigurations + ["--platform"] +
                    consumerEligiblePlatforms
                let yamlString = try shellGetStdout(
                    binaries.prepare.path,
                    args: args,
                    inDir: projectRoot.path,
                    environment: nil
                )
                let decoder = YAMLDecoder()
                let prepareResult = try decoder.decode(PrepareResult.self, from: yamlString, userInfo: [:])
                guard case .preparedFor(_, recommendedCacheAddress: let remote) = prepareResult else {
                    throw XcodeProjIntegrateError.noArtifactsToReuse
                }

                // Override the configuration again to include recommended cache address provided by xcprepare
                let finalOverride = IntegrationCacheConfig(
                    recommendedCacheAddress: remote,
                    xcccFile: binaries.cc.path,
                    mode: mode
                )
                try storeRCOverride(finalOverride, configOverrideLocation: configOverride)
            } catch {
                // integration cannot be done as `xccc` hasn't been generated
                exit(1, "XCRemoteCache cannot be initialized with a consumer mode. Error: \(error).")
            }
        }

        // modify .pbxproj
        let xcodeproj = try XcodeProj(path: projectPath)

        for target in xcodeproj.pbxproj.nativeTargets {
            guard targetIncludeOracle.shouldInclude(identifier: target.name) else {
                continue
            }
            guard let targetConfigurations = target.buildConfigurationList else {
                fatalError("Missing buildConfigurationList. Cannot apply")
            }

            // Apply settings for only few configurations
            let targetConfigurationsToIntegrate = targetConfigurations.buildConfigurations.filter {
                configurationIncludeOracle.shouldInclude(identifier: $0.name)
            }

            guard !targetConfigurationsToIntegrate.isEmpty else {
                // No need to append build phases if none of Configurations exist for that target
                continue
            }

            for buildConfiguration in targetConfigurationsToIntegrate {
                let initialSettings = buildConfiguration.buildSettings
                let finalSettings = buildSettingsAppender.appendToBuildSettings(
                    buildSettings: initialSettings,
                    wrappers: binaries
                )
                buildConfiguration.buildSettings = finalSettings
            }

            addSharedBuildPhases(target: target, in: xcodeproj.pbxproj)
            // Add producer build phase that marks given sha+configuration+platform as "ready to use"
            if case .producer = mode, finalProducerTarget == target.name {
                addFinalProducerBuildPhases(target: target, in: xcodeproj.pbxproj)
            }
        }

        try xcodeproj.write(path: outputPath)

        try lldbPatcher.enable()
    }